Revision: 12054
Author: [email protected]
Date: Thu Jul 12 02:37:16 2012
Log: Merged r12019 into 3.10 branch.
Original CL: http://codereview.chromium.org/10698123/
[email protected]
BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/10690162
http://code.google.com/p/v8/source/detail?r=12054
Modified:
/branches/3.10/src/debug.cc
/branches/3.10/src/execution.cc
/branches/3.10/src/runtime.cc
/branches/3.10/src/version.cc
/branches/3.10/test/cctest/test-debug.cc
=======================================
--- /branches/3.10/src/debug.cc Tue Apr 10 05:30:14 2012
+++ /branches/3.10/src/debug.cc Thu Jul 12 02:37:16 2012
@@ -989,18 +989,17 @@
it.Advance();
}
- // If we found original frame
- if (it.frame()->fp() == thread_local_.last_fp_) {
- if (step_count > 1) {
- // Save old count and action to continue stepping after
- // StepOut
- thread_local_.queued_step_count_ = step_count - 1;
- }
-
- // Set up for StepOut to reach target frame
- step_action = StepOut;
- step_count = count;
- }
+ // Check that we indeed found the frame we are looking for.
+ CHECK(!it.done() && (it.frame()->fp() == thread_local_.last_fp_));
+ if (step_count > 1) {
+ // Save old count and action to continue stepping after
+ // StepOut
+ thread_local_.queued_step_count_ = step_count - 1;
+ }
+
+ // Set up for StepOut to reach target frame
+ step_action = StepOut;
+ step_count = count;
}
// Clear all current stepping setup.
=======================================
--- /branches/3.10/src/execution.cc Tue Apr 10 05:30:14 2012
+++ /branches/3.10/src/execution.cc Thu Jul 12 02:37:16 2012
@@ -132,6 +132,12 @@
V8::FatalProcessOutOfMemory("JS", true);
}
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ // Reset stepping state when script exits with uncaught exception.
+ if (isolate->debugger()->IsDebuggerActive()) {
+ isolate->debug()->ClearStepping();
+ }
+#endif // ENABLE_DEBUGGER_SUPPORT
return Handle<Object>();
} else {
isolate->clear_pending_message();
=======================================
--- /branches/3.10/src/runtime.cc Mon May 21 06:42:45 2012
+++ /branches/3.10/src/runtime.cc Thu Jul 12 02:37:16 2012
@@ -4730,21 +4730,28 @@
// Check whether debugger and is about to step into the callback that is
passed
// to a built-in function such as Array.forEach.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
- if (!isolate->IsDebuggerActive()) return isolate->heap()->false_value();
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
+ return isolate->heap()->false_value();
+ }
CONVERT_ARG_CHECKED(Object, callback, 0);
// We do not step into the callback if it's a builtin or not even a
function.
if (!callback->IsJSFunction() ||
JSFunction::cast(callback)->IsBuiltin()) {
return isolate->heap()->false_value();
}
return isolate->heap()->true_value();
+#else
+ return isolate->heap()->false_value();
+#endif // ENABLE_DEBUGGER_SUPPORT
}
// Set one shot breakpoints for the callback function that is passed to a
// built-in function such as Array.forEach to enable stepping into the
callback.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate->debug();
- if (!debug->IsStepping()) return NULL;
+ if (!debug->IsStepping()) return isolate->heap()->undefined_value();
CONVERT_ARG_CHECKED(Object, callback, 0);
HandleScope scope(isolate);
Handle<SharedFunctionInfo>
shared_info(JSFunction::cast(callback)->shared());
@@ -4753,7 +4760,8 @@
// again, we need to clear the step out at this point.
debug->ClearStepOut();
debug->FloodWithOneShot(shared_info);
- return NULL;
+#endif // ENABLE_DEBUGGER_SUPPORT
+ return isolate->heap()->undefined_value();
}
=======================================
--- /branches/3.10/src/version.cc Mon Jul 2 06:09:25 2012
+++ /branches/3.10/src/version.cc Thu Jul 12 02:37:16 2012
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 10
#define BUILD_NUMBER 8
-#define PATCH_LEVEL 20
+#define PATCH_LEVEL 21
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.10/test/cctest/test-debug.cc Mon Apr 23 05:57:22 2012
+++ /branches/3.10/test/cctest/test-debug.cc Thu Jul 12 02:37:16 2012
@@ -7349,5 +7349,48 @@
inline_script->Run();
}
+
+static void DebugEventStepNext(v8::DebugEvent event,
+ v8::Handle<v8::Object> exec_state,
+ v8::Handle<v8::Object> event_data,
+ v8::Handle<v8::Value> data) {
+ if (event == v8::Break) {
+ PrepareStep(StepNext);
+ }
+}
+
+
+static void RunScriptInANewCFrame(const char* source) {
+ v8::TryCatch try_catch;
+ CompileRun(source);
+ CHECK(try_catch.HasCaught());
+}
+
+
+TEST(Regress131642) {
+ // Bug description:
+ // When doing StepNext through the first script, the debugger is not
reset
+ // after exiting through exception. A flawed implementation enabling the
+ // debugger to step into Array.prototype.forEach breaks inside the
callback
+ // for forEach in the second script under the assumption that we are in a
+ // recursive call. In an attempt to step out, we crawl the stack using
the
+ // recorded frame pointer from the first script and fail when not
finding it
+ // on the stack.
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ v8::Debug::SetDebugEventListener(DebugEventStepNext);
+
+ // We step through the first script. It exits through an exception. We
run
+ // this inside a new frame to record a different FP than the second
script
+ // would expect.
+ const char* script_1 = "debugger; throw new Error();";
+ RunScriptInANewCFrame(script_1);
+
+ // The second script uses forEach.
+ const char* script_2 = "[0].forEach(function() { });";
+ CompileRun(script_2);
+
+ v8::Debug::SetDebugEventListener(NULL);
+}
#endif // ENABLE_DEBUGGER_SUPPORT
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev