Make sure debugger is ready for breakpoins when we process 'debugger' statement.
On 'debugger' statement, if anything in debugger calls 'EnsureDebugInfo' on a function, EnsureDebugInfo would compile and substitute code without debug break slots. This causes weird behavior later when stepping fails to work (see added test as an example). This fix is to make sure the debugger is prepared for breakpoints in that case as well. Also adds extra testing for bug 468661. R=yangguo@chromium.org,yurys@chromium.orh BUG=v8:3990,chromium:468661 LOG=N Review URL: https://codereview.chromium.org/1032353002 Cr-Commit-Position: refs/heads/master@{#27502}
This commit is contained in:
parent
019096f829
commit
15ef61d468
11
src/debug.cc
11
src/debug.cc
@ -3089,8 +3089,19 @@ void Debug::HandleDebugBreak() {
|
||||
bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
|
||||
!isolate_->stack_guard()->CheckDebugBreak();
|
||||
|
||||
bool is_debugger_statement = !isolate_->stack_guard()->CheckDebugCommand() &&
|
||||
!isolate_->stack_guard()->CheckDebugBreak();
|
||||
|
||||
isolate_->stack_guard()->ClearDebugBreak();
|
||||
|
||||
if (is_debugger_statement) {
|
||||
// If we have been called via 'debugger' Javascript statement,
|
||||
// we might not be prepared for breakpoints.
|
||||
// TODO(dslomov,yangguo): CheckDebugBreak may race with RequestDebugBreak.
|
||||
// Revisit this to clean-up.
|
||||
HandleScope handle_scope(isolate_);
|
||||
PrepareForBreakPoints();
|
||||
}
|
||||
ProcessDebugMessages(debug_command_only);
|
||||
}
|
||||
|
||||
|
58
test/mjsunit/debug-allscopes-on-debugger.js
Normal file
58
test/mjsunit/debug-allscopes-on-debugger.js
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2015 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
|
||||
|
||||
Debug = debug.Debug
|
||||
var exception = null;
|
||||
var break_count = 0;
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
if (event == Debug.DebugEvent.Break) {
|
||||
assertTrue(exec_state.frameCount() != 0, "FAIL: Empty stack trace");
|
||||
// Count number of expected breakpoints in this source file.
|
||||
if (!break_count) {
|
||||
var source_text = exec_state.frame(0).func().script().source();
|
||||
expected_breaks = source_text.match(/\/\/\s*Break\s+\d+\./g).length;
|
||||
print("Expected breaks: " + expected_breaks);
|
||||
}
|
||||
var frameMirror = exec_state.frame(0);
|
||||
|
||||
frameMirror.allScopes();
|
||||
var source = frameMirror.sourceLineText();
|
||||
print("paused at: " + source);
|
||||
assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
|
||||
"Unexpected pause at: " + source + "\n" +
|
||||
"Expected: // Break " + break_count + ".");
|
||||
++break_count;
|
||||
|
||||
if (break_count !== expected_breaks) {
|
||||
exec_state.prepareStep(Debug.StepAction.StepIn, 1);
|
||||
print("Next step prepared");
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
print(e, e.stack);
|
||||
}
|
||||
};
|
||||
|
||||
Debug.setListener(listener);
|
||||
|
||||
var sum = 0;
|
||||
(function (){
|
||||
'use strict';
|
||||
|
||||
debugger; // Break 0.
|
||||
var i = 0; // Break 1.
|
||||
i++; // Break 2.
|
||||
i++; // Break 3.
|
||||
return i; // Break 4.
|
||||
}()); // Break 5.
|
||||
|
||||
assertNull(exception); // Break 6.
|
||||
assertEquals(expected_breaks, break_count);
|
||||
|
||||
Debug.setListener(null);
|
@ -29,7 +29,7 @@ function listener(event, exec_state, event_data, data) {
|
||||
} catch(e) {
|
||||
v = e;
|
||||
}
|
||||
|
||||
frameMirror.allScopes();
|
||||
var source = frameMirror.sourceLineText();
|
||||
print("paused at: " + source);
|
||||
assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
|
||||
|
Loading…
Reference in New Issue
Block a user