Commit ea48d094 authored by jgruber's avatar jgruber Committed by Commit bot

[debugger] Further stepping support in test wrapper

This CL adds further support to the test wrapper. We are now able to
run almost all mjsunit/debug-step-* tests using the inspector backend.

debug-stepframe-* tests are not yet supported since inspector does not
know a 'frame' step type.

The interface has also been improved to be able to move these tests to
inspector mostly without modification.

BUG=v8:5330

Review-Url: https://codereview.chromium.org/2466273005
Cr-Commit-Position: refs/heads/master@{#40800}
parent 78f0d04c
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --allow-natives-syntax
// This test tests that deoptimization due to debug breaks works for
// inlined functions where the full-code is generated before the
......@@ -33,7 +32,6 @@
//
//See http://code.google.com/p/chromium/issues/detail?id=105375
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
var count = 0;
......
......@@ -2,7 +2,6 @@
// 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 --allow-natives-syntax --crankshaft
Debug = debug.Debug;
......
......@@ -2,7 +2,6 @@
// 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
......
......@@ -2,7 +2,6 @@
// 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 --no-analyze-environment-liveness
// Test that debug-evaluate correctly collects free outer variables
// and does not get confused by variables in nested scopes.
......
......@@ -2,7 +2,6 @@
// 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
var Debug = debug.Debug;
......
......@@ -2,7 +2,6 @@
// 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
var Debug = debug.Debug;
......
......@@ -2,7 +2,6 @@
// 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 --allow-natives-syntax --use-inlining
var Debug = debug.Debug;
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Make sure printing different element kinds doesn't crash.
......
......@@ -2,7 +2,6 @@
// 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 --allow-natives-syntax
var Debug = debug.Debug;
var exception = null;
......
......@@ -2,7 +2,6 @@
// 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 --allow-natives-syntax
var Debug = debug.Debug;
var expected = ["debugger;", "debugger;"];
......
......@@ -2,7 +2,6 @@
// 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
......
......@@ -2,7 +2,6 @@
// 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
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
// Simple debug event handler which counts the number of breaks hit and steps.
......
......@@ -2,7 +2,7 @@
// 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 --turbo-filter=g --allow-natives-syntax
// Flags: --turbo-filter=g
// Test that Debug::PrepareForBreakPoints can deal with turbofan code (g)
// on the stack. Without deoptimization support, we will not be able to
......
......@@ -2,7 +2,6 @@
// 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 get() {
return 3; // Break
......
......@@ -25,9 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -2,7 +2,6 @@
// 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
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Test stepping into callbacks passed to builtin functions.
......
......@@ -25,9 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......@@ -88,8 +86,9 @@ for (var i = 0; i < 3; i++) {
expected_source_line_text = ' return "s"; // expected line';
step_in_count = 2;
// Set a break point and call to invoke the debug event listener.
Debug.setBreakPoint(testFunction, 1, 0);
const breakid = Debug.setBreakPoint(testFunction, 1, 0);
testFunction();
Debug.clearBreakPoint(breakid);
assertNull(exception);
assertEquals(3, state);
}
......@@ -104,8 +103,9 @@ for (var i = 0; i < 3; i++) {
expected_source_line_text = ' return "s2"; // expected line';
step_in_count = 1;
// Set a break point and call to invoke the debug event listener.
Debug.setBreakPoint(testFunction2, 2, 0);
const breakid = Debug.setBreakPoint(testFunction2, 2, 0);
testFunction2();
Debug.clearBreakPoint(breakid);
assertNull(exception);
assertEquals(3, state);
}
......
......@@ -2,7 +2,6 @@
// 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
var break_count = 0;
var exception = null;
......@@ -31,9 +30,7 @@ function g() {
new f();
}
Debug.setBreakPoint(g, 6, Debug.BreakPositionAlignment.BreakPosition);
print(Debug.showBreakPoints(g, undefined,
Debug.BreakPositionAlignment.BreakPosition));
Debug.setBreakPoint(g, 6);
g();
Debug.setListener(null);
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
// Simple debug event handler which counts the number of breaks hit and steps.
......@@ -38,9 +36,6 @@ function listener(event, exec_state, event_data, data) {
if (exec_state.frameCount() > 1) {
exec_state.prepareStep(Debug.StepAction.StepIn);
}
// Test that there is a script.
assertTrue(typeof(event_data.func().script()) == 'object');
}
};
......
......@@ -2,24 +2,17 @@
// 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
// Tests stepping into through Array.prototype.forEach callbacks.
Debug = debug.Debug
var exception = null;
var break_count = 0;
var expected_breaks = -1;
var expected_breaks = 11;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Break) {
assertTrue(exec_state.frameCount() != 0, "FAIL: Empty stack trace");
if (!break_count) {
// Count number of expected breakpoints in this source file.
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 source = exec_state.frame(0).sourceLineText();
print("paused at: " + source);
assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -25,8 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --nocrankshaft
// Get the Debug object exposed from the debug context global object.
// Flags: --nocrankshaft
Debug = debug.Debug
var exception = null;
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,7 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Check that the ScopeIterator can properly recreate the scope at
// every point when stepping through functions.
......
......@@ -25,9 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
var exception = null;
......
......@@ -3,4 +3,23 @@
# found in the LICENSE file.
[
[ALWAYS, {
# Issue 3660: Replacing activated TurboFan frames by unoptimized code does
# not work, but we expect it to not crash.
'debug/debug-step-turbofan': [PASS, FAIL],
}], # ALWAYS
##############################################################################
['gc_stress == True', {
# Skip tests not suitable for GC stress.
# Tests taking too long
'debug/debug-stepout-scope-part1': [SKIP],
'debug/debug-stepout-scope-part2': [SKIP],
'debug/debug-stepout-scope-part3': [SKIP],
'debug/debug-stepout-scope-part4': [SKIP],
'debug/debug-stepout-scope-part5': [SKIP],
'debug/debug-stepout-scope-part6': [SKIP],
'debug/debug-stepout-scope-part7': [SKIP],
'debug/debug-stepout-scope-part8': [SKIP],
}], # 'gc_stress == True'
]
......@@ -18,7 +18,7 @@ function receive(message) {
class DebugWrapper {
constructor() {
// Message dictionary storing {id, message} pairs.
this.receivedMessages = {};
this.receivedMessages = new Map();
// Each message dispatched by the Debug wrapper is assigned a unique number
// using nextMessageId.
......@@ -29,15 +29,39 @@ class DebugWrapper {
// TODO(jgruber): Determine which of these are still required and possible.
// Debug events which can occur in the V8 JavaScript engine.
this.DebugEvent = { Break: 1
, Exception: 2
, NewFunction: 3
, BeforeCompile: 4
, AfterCompile: 5
, CompileError: 6
, AsyncTaskEvent: 7
this.DebugEvent = { Break: 1,
Exception: 2,
NewFunction: 3,
BeforeCompile: 4,
AfterCompile: 5,
CompileError: 6,
AsyncTaskEvent: 7
};
// The different types of steps.
this.StepAction = { StepOut: 0,
StepNext: 1,
StepIn: 2,
StepFrame: 3,
};
// A copy of the scope types from runtime-debug.cc.
// NOTE: these constants should be backward-compatible, so
// add new ones to the end of this list.
this.ScopeType = { Global: 0,
Local: 1,
With: 2,
Closure: 3,
Catch: 4,
Block: 5,
Script: 6,
Eval: 7,
Module: 8
};
// Store the current script id so we can skip corresponding break events.
this.thisScriptId = %FunctionGetScriptId(receive);
// Register as the active wrapper.
assertTrue(activeWrapper === undefined);
activeWrapper = this;
......@@ -69,14 +93,15 @@ class DebugWrapper {
const {msgid, msg} = this.createMessage(
"Debugger.setBreakpoint",
{ location : { scriptId : scriptid.toString()
, lineNumber : loc.line
, columnNumber : loc.column
{ location : { scriptId : scriptid.toString(),
lineNumber : loc.line,
columnNumber : loc.column
}
});
this.sendMessage(msg);
const reply = this.receivedMessages[msgid];
const reply = this.takeReplyChecked(msgid);
assertTrue(reply.result !== undefined);
const breakid = reply.result.breakpointId;
assertTrue(breakid !== undefined);
......@@ -87,7 +112,7 @@ class DebugWrapper {
const {msgid, msg} = this.createMessage(
"Debugger.removeBreakpoint", { breakpointId : breakid });
this.sendMessage(msg);
assertTrue(this.receivedMessages[msgid] !== undefined);
this.takeReplyChecked(msgid);
}
// Returns the serialized result of the given expression. For example:
......@@ -95,12 +120,12 @@ class DebugWrapper {
evaluate(frameid, expression) {
const {msgid, msg} = this.createMessage(
"Debugger.evaluateOnCallFrame",
{ callFrameId : frameid
, expression : expression
{ callFrameId : frameid,
expression : expression
});
this.sendMessage(msg);
const reply = this.receivedMessages[msgid];
const reply = this.takeReplyChecked(msgid);
return reply.result.result;
}
......@@ -117,7 +142,7 @@ class DebugWrapper {
method: method,
params: params,
});
return {msgid: id, msg: msg};
return { msgid : id, msg: msg };
}
receiveMessage(message) {
......@@ -125,7 +150,7 @@ class DebugWrapper {
const parsedMessage = JSON.parse(message);
if (parsedMessage.id !== undefined) {
this.receivedMessages[parsedMessage.id] = parsedMessage;
this.receivedMessages.set(parsedMessage.id, parsedMessage);
}
this.dispatchMessage(parsedMessage);
......@@ -139,7 +164,44 @@ class DebugWrapper {
sendMessageForMethodChecked(method) {
const {msgid, msg} = this.createMessage(method);
this.sendMessage(msg);
assertTrue(this.receivedMessages[msgid] !== undefined);
this.takeReplyChecked(msgid);
}
takeReplyChecked(msgid) {
const reply = this.receivedMessages.get(msgid);
assertTrue(reply !== undefined);
this.receivedMessages.delete(msgid);
return reply;
}
execStatePrepareStep(action) {
switch(action) {
case this.StepAction.StepOut: this.stepOut(); break;
case this.StepAction.StepNext: this.stepOver(); break;
case this.StepAction.StepIn: this.stepInto(); break;
default: %AbortJS("Unsupported StepAction"); break;
}
}
execStateScope(scope) {
// TODO(jgruber): Mapping
return { scopeType: () => scope.type,
scopeObject: () => scope.object
};
}
execStateFrame(frame) {
const scriptid = parseInt(frame.location.scriptId);
const line = frame.location.lineNumber;
const column = frame.location.columnNumber;
const loc = %ScriptLocationFromLine2(scriptid, line, column, 0);
const func = { name : () => frame.functionName };
return { sourceLineText : () => loc.sourceText,
functionName : () => frame.functionName,
func : () => func,
scopeCount : () => frame.scopeChain.length,
scope : (index) => this.execStateScope(frame.scopeChain[index])
};
}
// --- Message handlers. -----------------------------------------------------
......@@ -156,15 +218,25 @@ class DebugWrapper {
handleDebuggerPaused(message) {
const params = message.params;
// Skip break events in this file.
if (params.callFrames[0].location.scriptId == this.thisScriptId) return;
// TODO(jgruber): Arguments as needed.
let execState = { frames: params.callFrames };
this.invokeListener(this.DebugEvent.Break, execState);
let execState = { frames : params.callFrames,
prepareStep : this.execStatePrepareStep.bind(this),
frame : (index) => this.execStateFrame(
index ? params.callFrames[index]
: params.callFrames[0]),
frameCount : () => params.callFrames.length
};
let eventData = this.execStateFrame(params.callFrames[0]);
this.invokeListener(this.DebugEvent.Break, execState, eventData);
}
handleDebuggerScriptParsed(message) {
const params = message.params;
let eventData = { scriptId : params.scriptId
, eventType : this.DebugEvent.AfterCompile
let eventData = { scriptId : params.scriptId,
eventType : this.DebugEvent.AfterCompile
}
// TODO(jgruber): Arguments as needed. Still completely missing exec_state,
......@@ -179,3 +251,13 @@ class DebugWrapper {
}
}
}
// Simulate the debug object generated by --expose-debug-as debug.
var debug = { instance : undefined };
Object.defineProperty(debug, 'Debug', { get: function() {
if (!debug.instance) {
debug.instance = new DebugWrapper();
debug.instance.enable();
}
return debug.instance;
}});
......@@ -59,10 +59,6 @@
'es6/debug-promises/reject-with-undefined-reject': [FAIL],
'es6/debug-promises/reject-with-invalid-reject': [FAIL],
# Issue 3660: Replacing activated TurboFan frames by unoptimized code does
# not work, but we expect it to not crash.
'debug-step-turbofan': [PASS, FAIL],
# Issue 5587: The eval'ed code is piped through Ignition and fails when being
# live edited. This needs investigation.
'debug-liveedit-double-call': [SKIP],
......@@ -209,7 +205,6 @@
'regress/regress-4121': [SKIP],
'compare-known-objects-slow': [SKIP],
# Tests taking too long
'debug-stepout-scope-part8': [SKIP],
'mirror-object': [SKIP],
'packed-elements': [SKIP],
'regress/regress-1122': [SKIP],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment