Reviewers: vsevik,

Message:
Please take a look.

Description:
Fix disabling all break points from within the debug event callback.

BUG=chromium:432493
LOG=Y

Please review this at https://codereview.chromium.org/728103008/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+74, -6 lines):
  M src/debug.h
  M src/debug.cc
  A test/mjsunit/regress/regress-crbug-432493.js


Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index 3029adba9d53403677ac35ed4ce05ba2ac7dfde3..1fad8f1e17faea70eed82b86da97fdef7a7a51b5 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -40,6 +40,7 @@ Debug::Debug(Isolate* isolate)
       live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
       has_break_points_(false),
       break_disabled_(false),
+      break_disabled_for_event_(false),
       break_on_exception_(false),
       break_on_uncaught_exception_(false),
       script_cache_(NULL),
@@ -872,7 +873,7 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
   LiveEdit::InitializeThreadLocal(this);

   // Just continue if breaks are disabled or debugger cannot be loaded.
-  if (break_disabled_) return;
+  if (break_disabled()) return;

   // Enter the debugger.
   DebugScope debug_scope(this);
@@ -2812,7 +2813,8 @@ void Debug::CallEventCallback(v8::DebugEvent event,
                               Handle<Object> exec_state,
                               Handle<Object> event_data,
                               v8::Debug::ClientData* client_data) {
-  DisableBreak no_break(this, true);
+  bool previous_break_disabled_for_event = break_disabled_for_event_;
+  break_disabled_for_event_ = true;
   if (event_listener_->IsForeign()) {
     // Invoke the C debug event listener.
     v8::Debug::EventCallback callback =
@@ -2836,6 +2838,7 @@ void Debug::CallEventCallback(v8::DebugEvent event,
     Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
                        global, arraysize(argv), argv);
   }
+  break_disabled_for_event_ = previous_break_disabled_for_event;
 }


@@ -3089,7 +3092,7 @@ void Debug::HandleDebugBreak() {
   // Ignore debug break during bootstrapping.
   if (isolate_->bootstrapper()->IsActive()) return;
   // Just continue if breaks are disabled.
-  if (break_disabled_) return;
+  if (break_disabled()) return;
   // Ignore debug break if debugger is not active.
   if (!is_active()) return;

Index: src/debug.h
diff --git a/src/debug.h b/src/debug.h
index b8348fd52af0dbd4656e4ea88ec3535d1656591b..7aa2f1387a5972bbd5b567c4ec349eeb282442b9 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -515,6 +515,9 @@ class Debug {
   // Check whether there are commands in the command queue.
   inline bool has_commands() const { return !command_queue_.IsEmpty(); }
inline bool ignore_events() const { return is_suppressed_ | | !is_active_; }
+  inline bool break_disabled() const {
+    return break_disabled_ || break_disabled_for_event_;
+  }

   void OnException(Handle<Object> exception, bool uncaught,
                    Handle<Object> promise);
@@ -592,6 +595,7 @@ class Debug {
   bool live_edit_enabled_;
   bool has_break_points_;
   bool break_disabled_;
+  bool break_disabled_for_event_;
   bool break_on_exception_;
   bool break_on_uncaught_exception_;

@@ -702,14 +706,21 @@ class DebugScope BASE_EMBEDDED {
 class DisableBreak BASE_EMBEDDED {
  public:
   explicit DisableBreak(Debug* debug, bool disable_break)
-    : debug_(debug), old_state_(debug->break_disabled_) {
+      : debug_(debug),
+        previous_break_disabled_(debug->break_disabled_),
+ previous_break_disabled_for_event_(debug->break_disabled_for_event_) {
     debug_->break_disabled_ = disable_break;
+    debug_->break_disabled_for_event_ = disable_break;
+  }
+  ~DisableBreak() {
+    debug_->break_disabled_ = previous_break_disabled_;
+    debug_->break_disabled_for_event_ = previous_break_disabled_for_event_;
   }
-  ~DisableBreak() { debug_->break_disabled_ = old_state_; }

  private:
   Debug* debug_;
-  bool old_state_;
+  bool previous_break_disabled_ : 1;
+  bool previous_break_disabled_for_event_ : 1;
   DISALLOW_COPY_AND_ASSIGN(DisableBreak);
 };

Index: test/mjsunit/regress/regress-crbug-432493.js
diff --git a/test/mjsunit/regress/regress-crbug-432493.js b/test/mjsunit/regress/regress-crbug-432493.js
new file mode 100644
index 0000000000000000000000000000000000000000..39a18e75a70030e8d74bbbbd36b09bc7907724c7
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-432493.js
@@ -0,0 +1,54 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+function f() {
+  var a = 1;
+  var b = 2;
+  return a + b;
+}
+
+var exception = null;
+var break_count = 0;
+var throw_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      break_count++;
+      // Disable all breakpoints from within the debug event callback.
+      Debug.debuggerFlags().breakPointsActive.setValue(false);
+    } else if (event = Debug.DebugEvent.Exception) {
+      throw_count++;
+      // Enable all breakpoints from within the debug event callback.
+      Debug.debuggerFlags().breakPointsActive.setValue(true);
+    }
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug = debug.Debug;
+
+Debug.setListener(listener);
+Debug.setBreakOnException();
+Debug.setBreakPoint(f, 2);
+
+f();
+f();
+
+// Trigger exception event.
+try { throw 1; } catch (e) {}
+
+f();
+f();
+
+Debug.setListener(null);
+Debug.clearBreakOnException();
+Debug.debuggerFlags().breakPointsActive.setValue(true);
+
+assertEquals(2, break_count);
+assertEquals(1, throw_count);
+assertNull(exception);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to