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
-~----------~----~----~----~------~----~------~--~---

Reply via email to