зеркало из https://github.com/mozilla/pjs.git
Bug 711164 - Add support for stepping to the debugger; r=rcampbell
This commit is contained in:
Родитель
c8d3972d1c
Коммит
0b5eee6844
|
@ -280,6 +280,27 @@ DebuggerView.Stackframes = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the step over button click event.
|
||||
*/
|
||||
_onStepOverClick: function DVF__onStepOverClick() {
|
||||
ThreadState.activeThread.stepOver();
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the step in button click event.
|
||||
*/
|
||||
_onStepInClick: function DVF__onStepInClick() {
|
||||
ThreadState.activeThread.stepIn();
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the step out button click event.
|
||||
*/
|
||||
_onStepOutClick: function DVF__onStepOutClick() {
|
||||
ThreadState.activeThread.stepOut();
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies if the active thread has more frames which need to be loaded.
|
||||
*/
|
||||
|
@ -296,10 +317,16 @@ DebuggerView.Stackframes = {
|
|||
initialize: function DVF_initialize() {
|
||||
let close = document.getElementById("close");
|
||||
let resume = document.getElementById("resume");
|
||||
let stepOver = document.getElementById("step-over");
|
||||
let stepIn = document.getElementById("step-in");
|
||||
let stepOut = document.getElementById("step-out");
|
||||
let frames = document.getElementById("stackframes");
|
||||
|
||||
close.addEventListener("click", this._onCloseButtonClick, false);
|
||||
resume.addEventListener("click", this._onResumeButtonClick, false);
|
||||
stepOver.addEventListener("click", this._onStepOverClick, false);
|
||||
stepIn.addEventListener("click", this._onStepInClick, false);
|
||||
stepOut.addEventListener("click", this._onStepOutClick, false);
|
||||
frames.addEventListener("scroll", this._onFramesScroll, false);
|
||||
window.addEventListener("resize", this._onFramesScroll, false);
|
||||
|
||||
|
@ -312,10 +339,16 @@ DebuggerView.Stackframes = {
|
|||
destroy: function DVF_destroy() {
|
||||
let close = document.getElementById("close");
|
||||
let resume = document.getElementById("resume");
|
||||
let stepOver = document.getElementById("step-over");
|
||||
let stepIn = document.getElementById("step-in");
|
||||
let stepOut = document.getElementById("step-out");
|
||||
let frames = this._frames;
|
||||
|
||||
close.removeEventListener("click", this._onCloseButtonClick, false);
|
||||
resume.removeEventListener("click", this._onResumeButtonClick, false);
|
||||
stepOver.removeEventListener("click", this._onStepOverClick, false);
|
||||
stepIn.removeEventListener("click", this._onStepInClick, false);
|
||||
stepOut.removeEventListener("click", this._onStepOutClick, false);
|
||||
frames.removeEventListener("click", this._onFramesClick, false);
|
||||
frames.removeEventListener("scroll", this._onFramesScroll, false);
|
||||
window.removeEventListener("resize", this._onFramesScroll, false);
|
||||
|
@ -1198,3 +1231,6 @@ let DVF = DebuggerView.Stackframes;
|
|||
DVF._onFramesScroll = DVF._onFramesScroll.bind(DVF);
|
||||
DVF._onCloseButtonClick = DVF._onCloseButtonClick.bind(DVF);
|
||||
DVF._onResumeButtonClick = DVF._onResumeButtonClick.bind(DVF);
|
||||
DVF._onStepOverClick = DVF._onStepOverClick.bind(DVF);
|
||||
DVF._onStepInClick = DVF._onStepInClick.bind(DVF);
|
||||
DVF._onStepOutClick = DVF._onStepOutClick.bind(DVF);
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
<xul:toolbar id="dbg-toolbar">
|
||||
<xul:button id="close">&debuggerUI.closeButton;</xul:button>
|
||||
<xul:button id="resume"/>
|
||||
<xul:button id="step-over">&debuggerUI.stepOverButton;</xul:button>
|
||||
<xul:button id="step-in">&debuggerUI.stepInButton;</xul:button>
|
||||
<xul:button id="step-out">&debuggerUI.stepOutButton;</xul:button>
|
||||
<xul:menulist id="scripts"/>
|
||||
</xul:toolbar>
|
||||
<div id="dbg-content" class="hbox flex">
|
||||
|
|
|
@ -19,6 +19,18 @@
|
|||
- button that closes the debugger UI. -->
|
||||
<!ENTITY debuggerUI.closeButton "Close">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.stepOverButton): This is the label for the
|
||||
- button that steps over a function call. -->
|
||||
<!ENTITY debuggerUI.stepOverButton "Step Over">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.stepInButton): This is the label for the
|
||||
- button that steps into a function call. -->
|
||||
<!ENTITY debuggerUI.stepInButton "Step In">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.stepOutButton): This is the label for the
|
||||
- button that steps out of a function call. -->
|
||||
<!ENTITY debuggerUI.stepOutButton "Step Out">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.stackTitle): This is the label for the
|
||||
- widget that displays the call stack frames in the debugger. -->
|
||||
<!ENTITY debuggerUI.stackTitle "Call stack">
|
||||
|
|
|
@ -541,12 +541,16 @@ ThreadClient.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Resume a paused thread.
|
||||
* Resume a paused thread. If the optional aLimit parameter is present, then
|
||||
* the thread will also pause when that limit is reached.
|
||||
*
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
* @param [optional] object aLimit
|
||||
* An object with a type property set to the appropriate limit (next,
|
||||
* step, or finish) per the remote debugging protocol specification.
|
||||
*/
|
||||
resume: function TC_resume(aOnResponse) {
|
||||
resume: function TC_resume(aOnResponse, aLimit) {
|
||||
this._assertPaused("resume");
|
||||
|
||||
// Put the client in a tentative "resuming" state so we can prevent
|
||||
|
@ -554,7 +558,8 @@ ThreadClient.prototype = {
|
|||
this._state = "resuming";
|
||||
|
||||
let self = this;
|
||||
let packet = { to: this._actor, type: DebugProtocolTypes.resume };
|
||||
let packet = { to: this._actor, type: DebugProtocolTypes.resume,
|
||||
resumeLimit: aLimit };
|
||||
this._client.request(packet, function(aResponse) {
|
||||
if (aResponse.error) {
|
||||
// There was an error resuming, back to paused state.
|
||||
|
@ -566,6 +571,36 @@ ThreadClient.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Step over a function call.
|
||||
*
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepOver: function TC_stepOver(aOnResponse) {
|
||||
this.resume(aOnResponse, { type: "next" });
|
||||
},
|
||||
|
||||
/**
|
||||
* Step into a function call.
|
||||
*
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepIn: function TC_stepIn(aOnResponse) {
|
||||
this.resume(aOnResponse, { type: "step" });
|
||||
},
|
||||
|
||||
/**
|
||||
* Step out of a function call.
|
||||
*
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepOut: function TC_stepOut(aOnResponse) {
|
||||
this.resume(aOnResponse, { type: "finish" });
|
||||
},
|
||||
|
||||
/**
|
||||
* Interrupt a running thread.
|
||||
*
|
||||
|
|
|
@ -197,12 +197,130 @@ ThreadActor.prototype = {
|
|||
return { type: "detached" };
|
||||
},
|
||||
|
||||
/**
|
||||
* Pause the debuggee, by entering a nested event loop, and return a 'paused'
|
||||
* packet to the client.
|
||||
*
|
||||
* @param Debugger.Frame aFrame
|
||||
* The newest debuggee frame in the stack.
|
||||
* @param object aReason
|
||||
* An object with a 'type' property containing the reason for the pause.
|
||||
*/
|
||||
_pauseAndRespond: function TA__pauseAndRespond(aFrame, aReason) {
|
||||
try {
|
||||
let packet = this._paused(aFrame);
|
||||
if (!packet) {
|
||||
return undefined;
|
||||
}
|
||||
packet.why = aReason;
|
||||
this.conn.send(packet);
|
||||
return this._nest();
|
||||
} catch(e) {
|
||||
Cu.reportError("Got an exception during TA__pauseAndRespond: " + e +
|
||||
": " + e.stack);
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to resume execution of the debuggee.
|
||||
*/
|
||||
onResume: function TA_onResume(aRequest) {
|
||||
if (aRequest && aRequest.forceCompletion) {
|
||||
// TODO: remove this when Debugger.Frame.prototype.pop is implemented in
|
||||
// bug 736733.
|
||||
if (typeof this.frame.pop != "function") {
|
||||
return { error: "notImplemented",
|
||||
message: "forced completion is not yet implemented." };
|
||||
}
|
||||
|
||||
this.dbg.getNewestFrame().pop(aRequest.completionValue);
|
||||
let packet = this._resumed();
|
||||
DebuggerServer.xpcInspector.exitNestedEventLoop();
|
||||
return { type: "resumeLimit", frameFinished: aRequest.forceCompletion };
|
||||
}
|
||||
|
||||
if (aRequest && aRequest.resumeLimit) {
|
||||
// Bind these methods because some of the hooks are called with 'this'
|
||||
// set to the current frame.
|
||||
let pauseAndRespond = this._pauseAndRespond.bind(this);
|
||||
let createValueGrip = this.createValueGrip.bind(this);
|
||||
|
||||
let startFrame = this._youngestFrame;
|
||||
let startLine;
|
||||
if (this._youngestFrame.script) {
|
||||
let offset = this._youngestFrame.offset;
|
||||
startLine = this._youngestFrame.script.getOffsetLine(offset);
|
||||
}
|
||||
|
||||
// Define the JS hook functions for stepping.
|
||||
|
||||
let onEnterFrame = function TA_onEnterFrame(aFrame) {
|
||||
return pauseAndRespond(aFrame, { type: "resumeLimit" });
|
||||
};
|
||||
|
||||
let onPop = function TA_onPop(aCompletion) {
|
||||
// onPop is called with 'this' set to the current frame.
|
||||
|
||||
// Note that we're popping this frame; we need to watch for
|
||||
// subsequent step events on its caller.
|
||||
this.reportedPop = true;
|
||||
|
||||
return pauseAndRespond(this, { type: "resumeLimit" });
|
||||
}
|
||||
|
||||
let onStep = function TA_onStep() {
|
||||
// onStep is called with 'this' set to the current frame.
|
||||
|
||||
// If we've changed frame or line, then report that.
|
||||
if (this !== startFrame ||
|
||||
(this.script &&
|
||||
this.script.getOffsetLine(this.offset) != startLine)) {
|
||||
return pauseAndRespond(this, { type: "resumeLimit" });
|
||||
}
|
||||
|
||||
// Otherwise, let execution continue.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
switch (aRequest.resumeLimit.type) {
|
||||
case "step":
|
||||
this.dbg.onEnterFrame = onEnterFrame;
|
||||
// Fall through.
|
||||
case "next":
|
||||
let stepFrame = this._getNextStepFrame(startFrame);
|
||||
if (stepFrame) {
|
||||
stepFrame.onStep = onStep;
|
||||
stepFrame.onPop = onPop;
|
||||
}
|
||||
break;
|
||||
case "finish":
|
||||
stepFrame = this._getNextStepFrame(startFrame);
|
||||
if (stepFrame) {
|
||||
stepFrame.onPop = onPop;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return { error: "badParameterType",
|
||||
message: "Unknown resumeLimit type" };
|
||||
}
|
||||
}
|
||||
let packet = this._resumed();
|
||||
DebuggerServer.xpcInspector.exitNestedEventLoop();
|
||||
return packet;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper method that returns the next frame when stepping.
|
||||
*/
|
||||
_getNextStepFrame: function TA__getNextStepFrame(aFrame) {
|
||||
let stepFrame = aFrame.reportedPop ? aFrame.older : aFrame;
|
||||
if (!stepFrame || !stepFrame.script) {
|
||||
stepFrame = null;
|
||||
}
|
||||
return stepFrame;
|
||||
},
|
||||
|
||||
onClientEvaluate: function TA_onClientEvaluate(aRequest) {
|
||||
if (this.state !== "paused") {
|
||||
return { error: "wrongState",
|
||||
|
@ -472,6 +590,13 @@ ThreadActor.prototype = {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
// Clear stepping hooks.
|
||||
this.dbg.onEnterFrame = undefined;
|
||||
if (aFrame) {
|
||||
aFrame.onStep = undefined;
|
||||
aFrame.onPop = undefined;
|
||||
}
|
||||
|
||||
this._state = "paused";
|
||||
|
||||
// Save the pause frame (if any) as the youngest frame for
|
||||
|
@ -730,19 +855,7 @@ ThreadActor.prototype = {
|
|||
* The stack frame that contained the debugger statement.
|
||||
*/
|
||||
onDebuggerStatement: function TA_onDebuggerStatement(aFrame) {
|
||||
try {
|
||||
let packet = this._paused(aFrame);
|
||||
if (!packet) {
|
||||
return undefined;
|
||||
}
|
||||
packet.why = { type: "debuggerStatement" };
|
||||
this.conn.send(packet);
|
||||
return this._nest();
|
||||
} catch(e) {
|
||||
Cu.reportError("Got an exception during onDebuggerStatement: " + e +
|
||||
": " + e.stack);
|
||||
return undefined;
|
||||
}
|
||||
return this._pauseAndRespond(aFrame, { type: "debuggerStatement" });
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1153,8 +1266,20 @@ FrameActor.prototype = {
|
|||
* The protocol request object.
|
||||
*/
|
||||
onPop: function FA_onPop(aRequest) {
|
||||
return { error: "notImplemented",
|
||||
message: "Popping frames is not yet implemented." };
|
||||
// TODO: remove this when Debugger.Frame.prototype.pop is implemented
|
||||
if (typeof this.frame.pop != "function") {
|
||||
return { error: "notImplemented",
|
||||
message: "Popping frames is not yet implemented." };
|
||||
}
|
||||
|
||||
while (this.frame != this.threadActor.dbg.getNewestFrame()) {
|
||||
this.threadActor.dbg.getNewestFrame().pop();
|
||||
}
|
||||
this.frame.pop(aRequest.completionValue);
|
||||
|
||||
// TODO: return the watches property when frame pop watch actors are
|
||||
// implemented.
|
||||
return { from: this.actorID };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1189,19 +1314,9 @@ BreakpointActor.prototype = {
|
|||
* The stack frame that contained the breakpoint.
|
||||
*/
|
||||
hit: function BA_hit(aFrame) {
|
||||
try {
|
||||
let packet = this.threadActor._paused(aFrame);
|
||||
if (!packet) {
|
||||
return undefined;
|
||||
}
|
||||
// TODO: add the rest of the breakpoints on that line.
|
||||
packet.why = { type: "breakpoint", actors: [ this.actorID ] };
|
||||
this.conn.send(packet);
|
||||
return this.threadActor._nest();
|
||||
} catch(e) {
|
||||
Cu.reportError("Got an exception during hit: " + e + ': ' + e.stack);
|
||||
return undefined;
|
||||
}
|
||||
// TODO: add the rest of the breakpoints on that line (bug 676602).
|
||||
let reason = { type: "breakpoint", actors: [ this.actorID ] };
|
||||
return this.threadActor._pauseAndRespond(aFrame, reason);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,9 @@ function run_test()
|
|||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient, "test-stack", function (aResponse, aThreadClient) {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_simple_breakpoint();
|
||||
});
|
||||
|
@ -27,10 +29,13 @@ function test_simple_breakpoint()
|
|||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
let path = getFilePath('test_breakpoint-01.js');
|
||||
gThreadClient.setBreakpoint({ url: path, line: gDebuggee.line0 + 3}, function (aResponse, bpClient) {
|
||||
let location = { url: path, line: gDebuggee.line0 + 3};
|
||||
gThreadClient.setBreakpoint(location, function (aResponse, bpClient) {
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -15,7 +15,9 @@ function run_test()
|
|||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient, "test-stack", function (aResponse, aThreadClient) {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_breakpoint_running();
|
||||
});
|
||||
|
@ -26,6 +28,7 @@ function run_test()
|
|||
function test_breakpoint_running()
|
||||
{
|
||||
let path = getFilePath('test_breakpoint-01.js');
|
||||
let location = { url: path, line: gDebuggee.line0 + 3};
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"var a = 1;\n" + // line0 + 1
|
||||
|
@ -34,10 +37,12 @@ function test_breakpoint_running()
|
|||
// Setting the breakpoint later should interrupt the debuggee.
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location);
|
||||
do_check_eq(aPacket.why.type, "interrupted");
|
||||
});
|
||||
|
||||
gThreadClient.setBreakpoint({ url: path, line: gDebuggee.line0 + 3}, function(aResponse) {
|
||||
gThreadClient.setBreakpoint(location, function(aResponse) {
|
||||
// Eval scripts don't stick around long enough for the breakpoint to be set,
|
||||
// so just make sure we got the expected response from the actor.
|
||||
do_check_eq(aResponse.error, "noScript");
|
||||
|
|
|
@ -37,6 +37,8 @@ function test_skip_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -36,6 +36,8 @@ function test_child_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -38,6 +38,8 @@ function test_child_skip_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -38,6 +38,8 @@ function test_nested_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -38,6 +38,8 @@ function test_second_child_skip_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -38,6 +38,8 @@ function test_child_skip_breakpoint()
|
|||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
|
|
@ -32,9 +32,14 @@ function test_remove_breakpoint()
|
|||
let path = getFilePath('test_breakpoint-09.js');
|
||||
let location = { url: path, line: gDebuggee.line0 + 1};
|
||||
gThreadClient.setBreakpoint(location, function (aResponse, bpClient) {
|
||||
// Check that the breakpoint has properly skipped forward one line.
|
||||
do_check_eq(aResponse.actualLocation.url, location.url);
|
||||
do_check_eq(aResponse.actualLocation.line, location.line + 1);
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.url, path);
|
||||
do_check_eq(aPacket.frame.where.line, location.line + 1);
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
do_check_eq(aPacket.why.actors[0], bpClient.actor);
|
||||
// Check that the breakpoint worked.
|
||||
|
@ -43,7 +48,8 @@ function test_remove_breakpoint()
|
|||
// Remove the breakpoint.
|
||||
bpClient.remove(function (aResponse) {
|
||||
done = true;
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
gThreadClient.addOneTimeListener("paused",
|
||||
function (aEvent, aPacket) {
|
||||
// The breakpoint should not be hit again.
|
||||
gThreadClient.resume(function () {
|
||||
do_check_true(false);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check basic step-over functionality.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_simple_stepping();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_simple_stepping()
|
||||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 2);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, undefined);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 3);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
// When leaving a stack frame the line number doesn't change.
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 3);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, 2);
|
||||
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
gThreadClient.stepOver();
|
||||
});
|
||||
gThreadClient.stepOver();
|
||||
|
||||
});
|
||||
gThreadClient.stepOver();
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n"); // line0 + 3
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check basic step-in functionality.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_simple_stepping();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_simple_stepping()
|
||||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 2);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, undefined);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 3);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
// When leaving a stack frame the line number doesn't change.
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 3);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, 2);
|
||||
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
gThreadClient.stepIn();
|
||||
});
|
||||
gThreadClient.stepIn();
|
||||
|
||||
});
|
||||
gThreadClient.stepIn();
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n"); // line0 + 3
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check basic step-out functionality.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_simple_stepping();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_simple_stepping()
|
||||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 4);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, 2);
|
||||
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
gThreadClient.stepOut();
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function f() {\n" + // line0 + 1
|
||||
" debugger;\n" + // line0 + 2
|
||||
" this.a = 1;\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n" + // line0 + 5
|
||||
"f();\n"); // line0 + 6
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check that stepping over a function call does not pause inside the function.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function () {
|
||||
attachTestGlobalClientAndResume(gClient,
|
||||
"test-stack",
|
||||
function (aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_simple_stepping();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_simple_stepping()
|
||||
{
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 5);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, undefined);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
// Check the return value.
|
||||
do_check_eq(aPacket.type, "paused");
|
||||
do_check_eq(aPacket.frame.where.line, gDebuggee.line0 + 6);
|
||||
do_check_eq(aPacket.why.type, "resumeLimit");
|
||||
// Check that stepping worked.
|
||||
do_check_eq(gDebuggee.a, 1);
|
||||
do_check_eq(gDebuggee.b, undefined);
|
||||
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
gThreadClient.stepOver();
|
||||
|
||||
});
|
||||
gThreadClient.stepOver();
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function f() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
"}\n" + // line0 + 3
|
||||
"debugger;\n" + // line0 + 4
|
||||
"f();\n" + // line0 + 5
|
||||
"let b = 2;\n"); // line0 + 6
|
||||
}
|
|
@ -49,3 +49,7 @@ tail =
|
|||
[test_objectgrips-03.js]
|
||||
[test_objectgrips-04.js]
|
||||
[test_interrupt.js]
|
||||
[test_stepping-01.js]
|
||||
[test_stepping-02.js]
|
||||
[test_stepping-03.js]
|
||||
[test_stepping-04.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче