Reviewers: Mads Ager, Søren Gjesse, Description: Debugger should not stop in its own code and in code of built-in functions since it may confuse user.
Debug break handler checks whether current function is a built-in or a debugger one and just resumes execution if it is. Please review this at http://codereview.chromium.org/160001 SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/ Affected files: M src/execution.cc M test/cctest/test-debug.cc Index: test/cctest/test-debug.cc =================================================================== --- test/cctest/test-debug.cc (revision 2523) +++ test/cctest/test-debug.cc (working copy) @@ -5295,3 +5295,63 @@ ClearBreakPointFromJS(sbp2); v8::Debug::SetMessageHandler2(NULL); } + + +static void BreakMessageHandler(const v8::Debug::Message& message) { + if (message.IsEvent() && message.GetEvent() == v8::Break) { + // Count the number of breaks. + break_point_hit_count++; + + v8::HandleScope scope; + v8::Handle<v8::String> json = message.GetJSON(); + + SendContinueCommand(); + } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { + v8::HandleScope scope; + + bool is_debug_break = i::StackGuard::IsDebugBreak(); + // Force DebugBreak flag while serializer is working. + i::StackGuard::DebugBreak(); + + // Force serialization to trigger some internal JS execution. + v8::Handle<v8::String> json = message.GetJSON(); + + // Restore previous state. + if (is_debug_break) { + i::StackGuard::DebugBreak(); + } else { + i::StackGuard::Continue(i::DEBUGBREAK); + } + } +} + + +// Test that if DebugBreak is forced it is ignored when code from +// debug-delay.js is executed. +TEST(NoDebugBreakInAfterCompileMessageHandler) { + v8::HandleScope scope; + DebugLocalContext env; + + // Register a debug event listener which sets the break flag and counts. + v8::Debug::SetMessageHandler2(BreakMessageHandler); + + // Set the debug break flag. + v8::Debug::DebugBreak(); + + // Create a function for testing stepping. + const char* src = "function f() { eval('var x = 10;'); } "; + v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); + + // There should be only one break event. + CHECK_EQ(1, break_point_hit_count); + + // Set the debug break flag again. + v8::Debug::DebugBreak(); + f->Call(env->Global(), 0, NULL); + // There should be one more break event when the script is evaluated in 'f'. + CHECK_EQ(2, break_point_hit_count); + + // Get rid of the debug message handler. + v8::Debug::SetMessageHandler2(NULL); + CheckDebuggerUnloaded(); +} Index: src/execution.cc =================================================================== --- src/execution.cc (revision 2523) +++ src/execution.cc (working copy) @@ -587,6 +587,23 @@ return Heap::undefined_value(); } + { + JavaScriptFrameIterator it; + ASSERT(!it.done()); + Object* fun = it.frame()->function(); + if (fun && fun->IsJSFunction()) { + GlobalObject* global = JSFunction::cast(fun)->context()->global(); + // Don't stop in builtin functions. + if (global == Top::context()->builtins()) { + return Heap::undefined_value(); + } + // Don't stop in debugger functions. + if (Debug::IsDebugGlobal(global)) { + return Heap::undefined_value(); + } + } + } + // Collect the break state before clearing the flags. bool debug_command_only = StackGuard::IsDebugCommand() && !StackGuard::IsDebugBreak(); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
