📄 debug.cc.svn-base
字号:
prev->set_next(current->next()); } current->debug_info()->shared()->set_debug_info(Heap::undefined_value()); delete current; // If there are no more debug info objects there are not more break // points. has_break_points_ = debug_info_list_ != NULL; return; } // Move to next in list. prev = current; current = current->next(); } UNREACHABLE();}void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { // Get the executing function in which the debug break occurred. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); if (!EnsureDebugInfo(shared)) { // Return if we failed to retrieve the debug info. return; } Handle<DebugInfo> debug_info = GetDebugInfo(shared); Handle<Code> code(debug_info->code()); Handle<Code> original_code(debug_info->original_code());#ifdef DEBUG // Get the code which is actually executing. Handle<Code> frame_code(frame->FindCode()); ASSERT(frame_code.is_identical_to(code));#endif // Find the call address in the running code. This address holds the call to // either a DebugBreakXXX or to the debug break return entry code if the // break point is still active after processing the break point. Address addr = frame->pc() - Assembler::kTargetAddrToReturnAddrDist; // Check if the location is at JS exit. bool at_js_exit = false; RelocIterator it(debug_info->code()); while (!it.done()) { if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { at_js_exit = it.rinfo()->pc() == addr - 1; } it.next(); } // Handle the jump to continue execution after break point depending on the // break location. if (at_js_exit) { // First check if the call in the code is still the debug break return // entry code. If it is the break point is still active. If not the break // point was removed during break point processing. if (Assembler::target_address_at(addr) == debug_break_return_entry()->entry()) { // Break point still active. Jump to the corresponding place in the // original code. addr += original_code->instruction_start() - code->instruction_start(); } // Move one byte back to where the call instruction was placed. thread_local_.after_break_target_ = addr - 1; } else { // Check if there still is a debug break call at the target address. If the // break point has been removed it will have disappeared. If it have // disappeared don't try to look in the original code as the running code // will have the right address. This takes care of the case where the last // break point is removed from the function and therefore no "original code" // is available. If the debug break call is still there find the address in // the original code. if (IsDebugBreak(Assembler::target_address_at(addr))) { // If the break point is still there find the call address which was // overwritten in the original code by the call to DebugBreakXXX. // Find the corresponding address in the original code. addr += original_code->instruction_start() - code->instruction_start(); } // Install jump to the call address in the original code. This will be the // call which was overwritten by the call to DebugBreakXXX. thread_local_.after_break_target_ = Assembler::target_address_at(addr); }}Code* Debug::GetCodeTarget(Address target) { // Maybe this can be refactored with the stuff in ic-inl.h? Code* result = Code::cast(HeapObject::FromAddress(target - Code::kHeaderSize)); return result;}bool Debug::IsDebugGlobal(GlobalObject* global) { return IsLoaded() && global == Debug::debug_context()->global();}bool Debugger::debugger_active_ = false;bool Debugger::compiling_natives_ = false;bool Debugger::is_loading_debugger_ = false;DebugMessageThread* Debugger::message_thread_ = NULL;v8::DebugMessageHandler Debugger::debug_message_handler_ = NULL;void* Debugger::debug_message_handler_data_ = NULL;Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, int argc, Object*** argv, bool* caught_exception) { ASSERT(Top::context() == *Debug::debug_context()); // Create the execution state object. Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); ASSERT(constructor->IsJSFunction()); if (!constructor->IsJSFunction()) { *caught_exception = true; return Factory::undefined_value(); } Handle<Object> js_object = Execution::TryCall( Handle<JSFunction>::cast(constructor), Handle<JSObject>(Debug::debug_context()->global()), argc, argv, caught_exception); return js_object;}Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { // Create the execution state object. Handle<Object> break_id = Factory::NewNumberFromInt(Top::break_id()); const int argc = 1; Object** argv[argc] = { break_id.location() }; return MakeJSObject(CStrVector("MakeExecutionState"), argc, argv, caught_exception);}Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, Handle<Object> break_points_hit, bool* caught_exception) { // Create the new break event object. const int argc = 2; Object** argv[argc] = { exec_state.location(), break_points_hit.location() }; return MakeJSObject(CStrVector("MakeBreakEvent"), argc, argv, caught_exception);}Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state, Handle<Object> exception, bool uncaught, bool* caught_exception) { // Create the new exception event object. const int argc = 3; Object** argv[argc] = { exec_state.location(), exception.location(), uncaught ? Factory::true_value().location() : Factory::false_value().location()}; return MakeJSObject(CStrVector("MakeExceptionEvent"), argc, argv, caught_exception);}Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function, bool* caught_exception) { // Create the new function event object. const int argc = 1; Object** argv[argc] = { function.location() }; return MakeJSObject(CStrVector("MakeNewFunctionEvent"), argc, argv, caught_exception);}Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script, Handle<Object> script_function, bool* caught_exception) { // Create the compile event object. Handle<Object> exec_state = MakeExecutionState(caught_exception); Handle<Object> script_source(script->source()); Handle<Object> script_name(script->name()); const int argc = 3; Object** argv[argc] = { script_source.location(), script_name.location(), script_function.location() }; return MakeJSObject(CStrVector("MakeCompileEvent"), argc, argv, caught_exception);}Handle<String> Debugger::ProcessRequest(Handle<Object> exec_state, Handle<Object> request, bool stopped) { // Get the function ProcessDebugRequest (declared in debug.js). Handle<JSFunction> process_denbug_request = Handle<JSFunction>(JSFunction::cast( Debug::debug_context()->global()->GetProperty( *Factory::LookupAsciiSymbol("ProcessDebugRequest")))); // Call ProcessDebugRequest expect String result. The ProcessDebugRequest // will never throw an exception (see debug.js). bool caught_exception; const int argc = 3; Object** argv[argc] = { exec_state.location(), request.location(), stopped ? Factory::true_value().location() : Factory::false_value().location()}; Handle<Object> result = Execution::TryCall(process_denbug_request, Factory::undefined_value(), argc, argv, &caught_exception); if (caught_exception) { return Factory::empty_symbol(); } return Handle<String>::cast(result);}void Debugger::OnException(Handle<Object> exception, bool uncaught) { HandleScope scope; // Bail out based on state or if there is no listener for this event if (Debug::InDebugger()) return; if (!Debugger::EventActive(v8::Exception)) return; // Bail out if exception breaks are not active if (uncaught) { // Uncaught exceptions are reported by either flags. if (!(Debug::break_on_uncaught_exception() || Debug::break_on_exception())) return; } else { // Caught exceptions are reported is activated. if (!Debug::break_on_exception()) return; } // Enter the debugger. Bail out if the debugger cannot be loaded. if (!Debug::Load()) return; SaveBreakFrame save; EnterDebuggerContext enter; // Clear all current stepping setup. Debug::ClearStepping(); // Create the event data object. bool caught_exception = false; Handle<Object> exec_state = MakeExecutionState(&caught_exception); Handle<Object> event_data; if (!caught_exception) { event_data = MakeExceptionEvent(exec_state, exception, uncaught, &caught_exception); } // Bail out and don't call debugger if exception. if (caught_exception) { return; } // Process debug event ProcessDebugEvent(v8::Exception, event_data); // Return to continue execution from where the exception was thrown.}void Debugger::OnDebugBreak(Handle<Object> break_points_hit) { HandleScope scope; // Debugger has already been entered by caller. ASSERT(Top::context() == *Debug::debug_context()); // Bail out if there is no listener for this event if (!Debugger::EventActive(v8::Break)) return; // Debugger must be entered in advance. ASSERT(Top::context() == *Debug::debug_context()); // Create the event data object. bool caught_exception = false; Handle<Object> exec_state = MakeExecutionState(&caught_exception); Handle<Object> event_data; if (!caught_exception) { event_data = MakeBreakEvent(exec_state, break_points_hit, &caught_exception); } // Bail out and don't call debugger if exception. if (caught_exception) { return; } // Process debug event ProcessDebugEvent(v8::Break, event_data);}void Debugger::OnBeforeCompile(Handle<Script> script) { HandleScope scope; // Bail out based on state or if there is no listener for this event if (Debug::InDebugger()) return; if (compiling_natives()) return; if (!EventActive(v8::BeforeCompile)) return; // Enter the debugger. Bail out if the debugger cannot be loaded. if (!Debug::Load()) return; SaveBreakFrame save; EnterDebuggerContext enter; // Create the event data object. bool caught_exception = false; Handle<Object> event_data = MakeCompileEvent(script, Factory::undefined_value(), &caught_exception); // Bail out and don't call debugger if exception. if (caught_exception) { return; } // Process debug event ProcessDebugEvent(v8::BeforeCompile, event_data);}// Handle debugger actions when a new script is compiled.void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) { HandleScope scope; // No compile events while compiling natives. if (compiling_natives()) return; // No more to do if not debugging. if (!debugger_active()) return; // Enter the debugger. Bail out if the debugger cannot be loaded. if (!Debug::Load()) return; SaveBreakFrame save; EnterDebuggerContext enter; // If debugging there might be script break points registered for this // script. Make sure that these break points are set. // Get the function UpdateScriptBreakPoints (defined in debug-delay.js). Handle<Object> update_script_break_points = Handle<Object>(Debug::debug_context()->global()->GetProperty( *Factory::LookupAsciiSymbol("UpdateScriptBreakPoints"))); if (!update_script_break_points->IsJSFunction()) { return; } ASSERT(update_script_break_points->IsJSFunction()); // Wrap the script object in a proper JS object before passing it // to JavaScript. Handle<JSValue> wrapper = GetScriptWrapper(script); // Call UpdateScriptBreakPoints expect no exceptions. bool caught_exception = false; const int argc = 1; Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) }; Handle<Object> result = Execution::TryCall( Handle<JSFunction>::cast(update_script_break_points), Top::builtins(), argc, argv, &caught_exception); if (caught_exception) { return; } // Bail out based on state or if there is no listener for this event if (Debug::InDebugger()) return; if (!Debugger::EventActive(v8::AfterCompile)) return; // Create the compile state object. Handle<Object> event_data = MakeCompileEvent(script, Factory::undefined_value(), &caught_exception); // Bail out and don't call debugger if exception. if (caught_exception) { return; } // Process debug event ProcessDebugEvent(v8::AfterCompile, event_data);}void Debugger::OnNewFunction(Handle<JSFunction> function) { return; HandleScope scope;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -