aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Guo <yangguo@chromium.org>2014-11-24 11:21:52 +0100
committerYang Guo <yangguo@chromium.org>2014-11-24 10:22:01 +0000
commitfe794eab84d4f5ab7455163b23d7e6a59eab6562 (patch)
tree7653716e27dc63e7de36f58943d3acab6ca8f0ab
parenteebbf6319a79e759c307eaf1ce85e1ffb6878298 (diff)
downloadv8-fe794eab84d4f5ab7455163b23d7e6a59eab6562.tar.gz
Version 3.30.33.4 (cherry-pick)
Merged 5bea77f786469ac81d1e2805b2d268d394520c27 Fix disabling all break points from within the debug event callback. BUG=chromium:432493 LOG=N R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/751833003 Cr-Commit-Position: refs/branch-heads/3.30@{#25258}
-rw-r--r--src/debug.cc9
-rw-r--r--src/debug.h17
-rw-r--r--src/version.cc2
-rw-r--r--test/mjsunit/regress/regress-crbug-432493.js57
4 files changed, 78 insertions, 7 deletions
diff --git a/src/debug.cc b/src/debug.cc
index 841b6cfa8..6ee52fabe 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),
+ in_debug_event_listener_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
script_cache_(NULL),
@@ -864,7 +865,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);
@@ -2781,7 +2782,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 = in_debug_event_listener_;
+ in_debug_event_listener_ = true;
if (event_listener_->IsForeign()) {
// Invoke the C debug event listener.
v8::Debug::EventCallback callback =
@@ -2805,6 +2807,7 @@ void Debug::CallEventCallback(v8::DebugEvent event,
Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
global, arraysize(argv), argv);
}
+ in_debug_event_listener_ = previous;
}
@@ -3058,7 +3061,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;
diff --git a/src/debug.h b/src/debug.h
index 2afe0f621..cb71ed5c9 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -511,6 +511,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_ || in_debug_event_listener_;
+ }
void OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise);
@@ -588,6 +591,7 @@ class Debug {
bool live_edit_enabled_;
bool has_break_points_;
bool break_disabled_;
+ bool in_debug_event_listener_;
bool break_on_exception_;
bool break_on_uncaught_exception_;
@@ -698,14 +702,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_in_debug_event_listener_(debug->in_debug_event_listener_) {
debug_->break_disabled_ = disable_break;
+ debug_->in_debug_event_listener_ = disable_break;
+ }
+ ~DisableBreak() {
+ debug_->break_disabled_ = previous_break_disabled_;
+ debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
}
- ~DisableBreak() { debug_->break_disabled_ = old_state_; }
private:
Debug* debug_;
- bool old_state_;
+ bool previous_break_disabled_;
+ bool previous_in_debug_event_listener_;
DISALLOW_COPY_AND_ASSIGN(DisableBreak);
};
diff --git a/src/version.cc b/src/version.cc
index 52cbc9bb1..c67199a75 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 30
#define BUILD_NUMBER 33
-#define PATCH_LEVEL 3
+#define PATCH_LEVEL 4
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/test/mjsunit/regress/regress-crbug-432493.js b/test/mjsunit/regress/regress-crbug-432493.js
new file mode 100644
index 000000000..87c4f8398
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-432493.js
@@ -0,0 +1,57 @@
+// 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();
+
+assertEquals(1, break_count);
+assertEquals(0, throw_count);
+
+// 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);