mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1230345 - kill breakpoint sliding for most scenarios, only do it when we know we have scripts r=fitzgen
This commit is contained in:
parent
6c69904a09
commit
da676fb17f
@ -79,15 +79,13 @@ function testSetBreakpointBlankLine() {
|
||||
let sourceForm = getSourceForm(gSources, COFFEE_URL);
|
||||
|
||||
let source = gDebugger.gThreadClient.source(sourceForm);
|
||||
source.setBreakpoint({ line: 7 }, aResponse => {
|
||||
source.setBreakpoint({ line: 8 }, aResponse => {
|
||||
ok(!aResponse.error,
|
||||
"Should be able to set a breakpoint in a coffee source file on a blank line.");
|
||||
ok(aResponse.actualLocation,
|
||||
"Because 7 is empty, we should have an actualLocation.");
|
||||
is(aResponse.actualLocation.source.url, COFFEE_URL,
|
||||
"actualLocation.actor should be source mapped to the coffee file.");
|
||||
is(aResponse.actualLocation.line, 8,
|
||||
"actualLocation.line should be source mapped back to 8.");
|
||||
"Should be able to set a breakpoint in a coffee source file on a blank line.");
|
||||
ok(!aResponse.isPending,
|
||||
"Should not be a pending breakpoint.");
|
||||
ok(!aResponse.actualLocation,
|
||||
"Should not be a moved breakpoint.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
@ -2724,245 +2724,93 @@ SourceActor.prototype = {
|
||||
* @returns A Promise that resolves to the given BreakpointActor.
|
||||
*/
|
||||
_setBreakpoint: function (actor) {
|
||||
let { originalLocation } = actor;
|
||||
let { originalSourceActor, originalLine, originalColumn } = originalLocation;
|
||||
const { originalLocation } = actor;
|
||||
const { originalLine, originalSourceActor } = originalLocation;
|
||||
|
||||
return this._setBreakpointAtOriginalLocation(actor, originalLocation)
|
||||
.then((actualLocation) => {
|
||||
if (actualLocation) {
|
||||
return actualLocation;
|
||||
}
|
||||
|
||||
// There were no scripts that matched the given location, so we need to
|
||||
// perform breakpoint sliding. We try to slide the breakpoint by column
|
||||
// first, and if that fails, by line instead.
|
||||
if (!this.isSourceMapped) {
|
||||
if (originalColumn !== undefined) {
|
||||
// To perform breakpoint sliding for column breakpoints, we need to
|
||||
// build a map from column numbers to a list of entry points for each
|
||||
// column, implemented as a sparse array. An entry point is a (script,
|
||||
// offsets) pair, and represents all offsets in that script that are
|
||||
// entry points for the corresponding column.
|
||||
let columnToEntryPointsMap = [];
|
||||
|
||||
// Iterate over all scripts that correspond to this source actor and
|
||||
// line number.
|
||||
let scripts = this.scripts.getScriptsBySourceActor(this, originalLine);
|
||||
for (let script of scripts) {
|
||||
let columnToOffsetMap = script.getAllColumnOffsets()
|
||||
.filter(({ lineNumber }) => {
|
||||
return lineNumber === originalLine;
|
||||
})
|
||||
|
||||
// Iterate over each column, and add their list of offsets to the
|
||||
// map from column numbers to entry points by forming a (script,
|
||||
// offsets) pair, where script is the current script, and offsets is
|
||||
// the list of offsets for the current column.
|
||||
for (let { columnNumber: column, offset } of columnToOffsetMap) {
|
||||
let entryPoints = columnToEntryPointsMap[column];
|
||||
if (!entryPoints) {
|
||||
// We dont have a list of entry points for the current column
|
||||
// number yet, so create it and add it to the map.
|
||||
entryPoints = [];
|
||||
columnToEntryPointsMap[column] = entryPoints;
|
||||
}
|
||||
entryPoints.push({ script, offsets: [offset] });
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have a map from column numbers to a list of entry points
|
||||
// for each column, we can use it to perform breakpoint sliding. Start
|
||||
// at the original column of the breakpoint actor, and keep
|
||||
// incrementing it by one, until either we find a line that has at
|
||||
// least one entry point, or we go past the last column in the map.
|
||||
//
|
||||
// Note that by computing the entire map up front, and implementing it
|
||||
// as a sparse array, we can easily tell when we went past the last
|
||||
// column in the map.
|
||||
let actualColumn = originalColumn + 1;
|
||||
while (actualColumn < columnToEntryPointsMap.length) {
|
||||
let entryPoints = columnToEntryPointsMap[actualColumn];
|
||||
if (entryPoints) {
|
||||
setBreakpointAtEntryPoints(actor, entryPoints);
|
||||
return new OriginalLocation(
|
||||
originalSourceActor,
|
||||
originalLine,
|
||||
actualColumn
|
||||
);
|
||||
}
|
||||
++actualColumn;
|
||||
}
|
||||
|
||||
return originalLocation;
|
||||
} else {
|
||||
// To perform breakpoint sliding for line breakpoints, we need to
|
||||
// build a map from line numbers to a list of entry points for each
|
||||
// line, implemented as a sparse array. An entry point is a (script,
|
||||
// offsets) pair, and represents all offsets in that script that are
|
||||
// entry points for the corresponding line.
|
||||
let lineToEntryPointsMap = [];
|
||||
|
||||
// Iterate over all scripts that correspond to this source actor.
|
||||
let scripts = this.scripts.getScriptsBySourceActor(this);
|
||||
for (let script of scripts) {
|
||||
// Get all offsets for each line in the current script. This returns
|
||||
// a map from line numbers fo a list of offsets for each line,
|
||||
// implemented as a sparse array.
|
||||
let lineToOffsetsMap = script.getAllOffsets();
|
||||
|
||||
// Iterate over each line, and add their list of offsets to the map
|
||||
// from line numbers to entry points by forming a (script, offsets)
|
||||
// pair, where script is the current script, and offsets is the list
|
||||
// of offsets for the current line.
|
||||
for (let line = 0; line < lineToOffsetsMap.length; ++line) {
|
||||
let offsets = lineToOffsetsMap[line];
|
||||
if (offsets) {
|
||||
let entryPoints = lineToEntryPointsMap[line];
|
||||
if (!entryPoints) {
|
||||
// We dont have a list of entry points for the current line
|
||||
// number yet, so create it and add it to the map.
|
||||
entryPoints = [];
|
||||
lineToEntryPointsMap[line] = entryPoints;
|
||||
}
|
||||
entryPoints.push({ script, offsets });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have a map from line numbers to a list of entry points
|
||||
// for each line, we can use it to perform breakpoint sliding. Start
|
||||
// at the original line of the breakpoint actor, and keep incrementing
|
||||
// it by one, until either we find a line that has at least one entry
|
||||
// point, or we go past the last line in the map.
|
||||
//
|
||||
// Note that by computing the entire map up front, and implementing it
|
||||
// as a sparse array, we can easily tell when we went past the last
|
||||
// line in the map.
|
||||
let actualLine = originalLine + 1;
|
||||
while (actualLine < lineToEntryPointsMap.length) {
|
||||
let entryPoints = lineToEntryPointsMap[actualLine];
|
||||
if (entryPoints) {
|
||||
setBreakpointAtEntryPoints(actor, entryPoints);
|
||||
break;
|
||||
}
|
||||
++actualLine;
|
||||
}
|
||||
if (actualLine >= lineToEntryPointsMap.length) {
|
||||
// We went past the last line in the map, so breakpoint sliding
|
||||
// failed. Keep the BreakpointActor in the BreakpointActorMap as a
|
||||
// pending breakpoint, so we can try again whenever a new script is
|
||||
// introduced.
|
||||
return originalLocation;
|
||||
}
|
||||
|
||||
return new OriginalLocation(
|
||||
originalSourceActor,
|
||||
actualLine
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let slideByColumn = (actualColumn) => {
|
||||
return this.sources.getAllGeneratedLocations(new OriginalLocation(
|
||||
this,
|
||||
originalLine,
|
||||
actualColumn
|
||||
)).then((generatedLocations) => {
|
||||
// Because getAllGeneratedLocations will always return the list of
|
||||
// generated locations for the closest column that is greater than
|
||||
// the one we are searching for if no exact match can be found, if
|
||||
// the list of generated locations is empty, we've reached the end
|
||||
// of the original line, and sliding continues by line.
|
||||
if (generatedLocations.length === 0) {
|
||||
return slideByLine(originalLine + 1);
|
||||
}
|
||||
|
||||
// If at least one script has an offset that matches one of the
|
||||
// generated locations in the list, then breakpoint sliding
|
||||
// succeeded.
|
||||
if (this._setBreakpointAtAllGeneratedLocations(actor, generatedLocations)) {
|
||||
return this.threadActor.sources.getOriginalLocation(generatedLocations[0]);
|
||||
}
|
||||
|
||||
// Try the next column in the original source.
|
||||
return slideByColumn(actualColumn + 1);
|
||||
});
|
||||
};
|
||||
|
||||
let slideByLine = (actualLine) => {
|
||||
return this.sources.getAllGeneratedLocations(new OriginalLocation(
|
||||
this,
|
||||
actualLine
|
||||
)).then((generatedLocations) => {
|
||||
// Because getAllGeneratedLocations will always return the list of
|
||||
// generated locations for the closest line that is greater than
|
||||
// the one we are searching for if no exact match can be found, if
|
||||
// the list of generated locations is empty, we've reached the end
|
||||
// of the original source, and breakpoint sliding failed.
|
||||
if (generatedLocations.length === 0) {
|
||||
return originalLocation;
|
||||
}
|
||||
|
||||
// If at least one script has an offset that matches one of the
|
||||
// generated locations in the list, then breakpoint sliding
|
||||
// succeeded.
|
||||
if (this._setBreakpointAtAllGeneratedLocations(actor, generatedLocations)) {
|
||||
return this.threadActor.sources.getOriginalLocation(generatedLocations[0]);
|
||||
}
|
||||
|
||||
// Try the next line in the original source.
|
||||
return slideByLine(actualLine + 1);
|
||||
});
|
||||
};
|
||||
|
||||
if (originalColumn !== undefined) {
|
||||
return slideByColumn(originalColumn + 1);
|
||||
} else {
|
||||
return slideByLine(originalLine + 1);
|
||||
}
|
||||
}
|
||||
}).then((actualLocation) => {
|
||||
// If the actual location on which the BreakpointActor ended up being
|
||||
// set differs from the original line that was requested, both the
|
||||
// BreakpointActor and the BreakpointActorMap need to be updated
|
||||
// accordingly.
|
||||
if (!actualLocation.equals(originalLocation)) {
|
||||
let existingActor = this.breakpointActorMap.getActor(actualLocation);
|
||||
if (existingActor) {
|
||||
actor.onDelete();
|
||||
this.breakpointActorMap.deleteActor(originalLocation);
|
||||
actor = existingActor;
|
||||
} else {
|
||||
this.breakpointActorMap.deleteActor(originalLocation);
|
||||
actor.originalLocation = actualLocation;
|
||||
this.breakpointActorMap.setActor(actualLocation, actor);
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
});
|
||||
},
|
||||
|
||||
_setBreakpointAtOriginalLocation: function (actor, originalLocation) {
|
||||
if (!this.isSourceMapped) {
|
||||
if (!this._setBreakpointAtGeneratedLocation(
|
||||
actor,
|
||||
GeneratedLocation.fromOriginalLocation(originalLocation)
|
||||
)) {
|
||||
return promise.resolve(null);
|
||||
}
|
||||
const scripts = this.scripts.getScriptsBySourceActorAndLine(
|
||||
this,
|
||||
originalLine
|
||||
);
|
||||
|
||||
return promise.resolve(originalLocation);
|
||||
} else {
|
||||
return this.sources.getAllGeneratedLocations(originalLocation)
|
||||
.then((generatedLocations) => {
|
||||
if (!this._setBreakpointAtAllGeneratedLocations(
|
||||
actor,
|
||||
generatedLocations
|
||||
)) {
|
||||
return null;
|
||||
// Never do breakpoint sliding for column breakpoints.
|
||||
// Additionally, never do breakpoint sliding if no scripts
|
||||
// exist on this line.
|
||||
//
|
||||
// Sliding can go horribly wrong if we always try to find the
|
||||
// next line with valid entry points in the entire file.
|
||||
// Scripts may be completely GCed and we never knew they
|
||||
// existed, so we end up sliding through whole functions to
|
||||
// the user's bewilderment.
|
||||
//
|
||||
// We can slide reliably if any scripts exist, however, due
|
||||
// to how scripts are kept alive. A parent Debugger.Script
|
||||
// keeps all of its children alive, so as long as we have a
|
||||
// valid script, we can slide through it and know we won't
|
||||
// slide through any of its child scripts. Additionally, if a
|
||||
// script gets GCed, that means that all parents scripts are
|
||||
// GCed as well, and no scripts will exist on those lines
|
||||
// anymore. We will never slide through a GCed script.
|
||||
if (originalLocation.originalColumn || scripts.length === 0) {
|
||||
return promise.resolve(actor);
|
||||
}
|
||||
|
||||
return this.threadActor.sources.getOriginalLocation(generatedLocations[0]);
|
||||
// Find the script that spans the largest amount of code to
|
||||
// determine the bounds for sliding.
|
||||
const largestScript = scripts.reduce((largestScript, script) => {
|
||||
if (script.lineCount > largestScript.lineCount) {
|
||||
return script;
|
||||
}
|
||||
return largestScript;
|
||||
});
|
||||
const maxLine = largestScript.startLine + largestScript.lineCount - 1;
|
||||
|
||||
let actualLine = originalLine;
|
||||
for (; actualLine <= maxLine; actualLine++) {
|
||||
const loc = new GeneratedLocation(this, actualLine);
|
||||
if (this._setBreakpointAtGeneratedLocation(actor, loc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The above loop should never complete. We only did breakpoint sliding
|
||||
// because we found scripts on the line we started from,
|
||||
// which means there must be valid entry points somewhere
|
||||
// within those scripts.
|
||||
assert(
|
||||
actualLine <= maxLine,
|
||||
"Could not find any entry points to set a breakpoint on, " +
|
||||
"even though I was told a script existed on the line I started " +
|
||||
"the search with."
|
||||
);
|
||||
|
||||
// Update the actor to use the new location (reusing a
|
||||
// previous breakpoint if it already exists on that line).
|
||||
const actualLocation = new OriginalLocation(originalSourceActor, actualLine);
|
||||
const existingActor = this.breakpointActorMap.getActor(actualLocation);
|
||||
this.breakpointActorMap.deleteActor(originalLocation);
|
||||
if (existingActor) {
|
||||
actor.onDelete();
|
||||
actor = existingActor;
|
||||
} else {
|
||||
actor.originalLocation = actualLocation;
|
||||
this.breakpointActorMap.setActor(actualLocation, actor);
|
||||
}
|
||||
}
|
||||
|
||||
return promise.resolve(actor);
|
||||
} else {
|
||||
return this.sources.getAllGeneratedLocations(originalLocation).then((generatedLocations) => {
|
||||
this._setBreakpointAtAllGeneratedLocations(
|
||||
actor,
|
||||
generatedLocations
|
||||
);
|
||||
|
||||
return actor;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -632,8 +632,8 @@ TabSources.prototype = {
|
||||
originalColumn
|
||||
} = originalLocation;
|
||||
|
||||
let source = originalSourceActor.source ||
|
||||
originalSourceActor.generatedSource;
|
||||
let source = (originalSourceActor.source ||
|
||||
originalSourceActor.generatedSource);
|
||||
|
||||
return this.fetchSourceMap(source).then((map) => {
|
||||
if (map) {
|
||||
|
@ -65,9 +65,11 @@ function test_simple_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
Components.utils.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n", // line0 + 3
|
||||
gDebuggee);
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n", // line0 + 3
|
||||
gDebuggee
|
||||
);
|
||||
}
|
||||
|
@ -57,8 +57,11 @@ function test_breakpoint_running()
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" +
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n"); // line0 + 3
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" +
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"var b = 2;\n", // line0 + 3
|
||||
gDebuggee
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check that setting a breakpoint in a line without code will skip forward.
|
||||
* Check that setting a breakpoint on a line without code will skip
|
||||
* forward when we know the script isn't GCed (the debugger is connected,
|
||||
* so it's kept alive).
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
@ -65,14 +67,18 @@ function test_skip_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
// Continue until the breakpoint is hit.
|
||||
gThreadClient.resume();
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"// A comment.\n" + // line0 + 3
|
||||
"var b = 2;"); // line0 + 4
|
||||
// Use `evalInSandbox` to make the debugger treat it as normal
|
||||
// globally-scoped code, where breakpoint sliding rules apply.
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = 1;\n" + // line0 + 2
|
||||
"// A comment.\n" + // line0 + 3
|
||||
"var b = 2;", // line0 + 4
|
||||
gDebuggee
|
||||
);
|
||||
}
|
||||
|
@ -67,11 +67,14 @@ function test_child_breakpoint()
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" this.b = 2;\n" + // line0 + 3
|
||||
"}\n" + // line0 + 4
|
||||
"debugger;\n" + // line0 + 5
|
||||
"foo();\n"); // line0 + 6
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" this.b = 2;\n" + // line0 + 3
|
||||
"}\n" + // line0 + 4
|
||||
"debugger;\n" + // line0 + 5
|
||||
"foo();\n", // line0 + 6
|
||||
gDebuggee
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check that setting a breakpoint in a line without code in a child scrip
|
||||
* Check that setting a breakpoint in a line without code in a child script
|
||||
* will skip forward.
|
||||
*/
|
||||
|
||||
@ -68,12 +68,15 @@ function test_child_skip_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"foo();\n"); // line0 + 7
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"foo();\n", // line0 + 7
|
||||
gDebuggee
|
||||
);
|
||||
}
|
||||
|
@ -69,18 +69,21 @@ function test_nested_breakpoint()
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" function bar() {\n" + // line0 + 2
|
||||
" function baz() {\n" + // line0 + 3
|
||||
" this.a = 1;\n" + // line0 + 4
|
||||
" // A comment.\n" + // line0 + 5
|
||||
" this.b = 2;\n" + // line0 + 6
|
||||
" }\n" + // line0 + 7
|
||||
" baz();\n" + // line0 + 8
|
||||
" }\n" + // line0 + 9
|
||||
" bar();\n" + // line0 + 10
|
||||
"}\n" + // line0 + 11
|
||||
"debugger;\n" + // line0 + 12
|
||||
"foo();\n"); // line0 + 13
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" function bar() {\n" + // line0 + 2
|
||||
" function baz() {\n" + // line0 + 3
|
||||
" this.a = 1;\n" + // line0 + 4
|
||||
" // A comment.\n" + // line0 + 5
|
||||
" this.b = 2;\n" + // line0 + 6
|
||||
" }\n" + // line0 + 7
|
||||
" baz();\n" + // line0 + 8
|
||||
" }\n" + // line0 + 9
|
||||
" bar();\n" + // line0 + 10
|
||||
"}\n" + // line0 + 11
|
||||
"debugger;\n" + // line0 + 12
|
||||
"foo();\n", // line0 + 13
|
||||
gDebuggee
|
||||
)
|
||||
}
|
||||
|
@ -68,15 +68,18 @@ function test_second_child_skip_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" bar();\n" + // line0 + 2
|
||||
"}\n" + // line0 + 3
|
||||
"function bar() {\n" + // line0 + 4
|
||||
" this.a = 1;\n" + // line0 + 5
|
||||
" // A comment.\n" + // line0 + 6
|
||||
" this.b = 2;\n" + // line0 + 7
|
||||
"}\n" + // line0 + 8
|
||||
"debugger;\n" + // line0 + 9
|
||||
"foo();\n"); // line0 + 10
|
||||
Cu.evalInSandbox(
|
||||
"var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" bar();\n" + // line0 + 2
|
||||
"}\n" + // line0 + 3
|
||||
"function bar() {\n" + // line0 + 4
|
||||
" this.a = 1;\n" + // line0 + 5
|
||||
" // A comment.\n" + // line0 + 6
|
||||
" this.b = 2;\n" + // line0 + 7
|
||||
"}\n" + // line0 + 8
|
||||
"debugger;\n" + // line0 + 9
|
||||
"foo();\n", // line0 + 10
|
||||
gDebuggee
|
||||
)
|
||||
}
|
||||
|
@ -48,8 +48,7 @@ function test_child_skip_breakpoint()
|
||||
let location = { line: gDebuggee.line0 + 3 };
|
||||
|
||||
source.setBreakpoint(location, function (aResponse, bpClient) {
|
||||
// Check that the breakpoint has properly skipped forward one
|
||||
// line.
|
||||
// Check that the breakpoint has properly skipped forward one line.
|
||||
do_check_eq(aResponse.actualLocation.source.actor, source.actor);
|
||||
do_check_eq(aResponse.actualLocation.line, location.line + 1);
|
||||
|
||||
@ -78,13 +77,20 @@ function test_child_skip_breakpoint()
|
||||
}
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 3
|
||||
"}\n"); // line0 + 4
|
||||
gDebuggee.eval("var line1 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line1 + 1
|
||||
"foo();\n"); // line1 + 2
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n", // line0 + 5
|
||||
gDebuggee,
|
||||
"1.7",
|
||||
"script1.js");
|
||||
|
||||
Cu.evalInSandbox("var line1 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line1 + 1
|
||||
"foo();\n", // line1 + 2
|
||||
gDebuggee,
|
||||
"1.7",
|
||||
"script2.js");
|
||||
}
|
||||
|
@ -71,15 +71,16 @@ function test_remove_breakpoint()
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo(stop) {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" if (stop) return;\n" + // line0 + 3
|
||||
" delete this.a;\n" + // line0 + 4
|
||||
" foo(true);\n" + // line0 + 5
|
||||
"}\n" + // line0 + 6
|
||||
"debugger;\n" + // line1 + 7
|
||||
"foo();\n"); // line1 + 8
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"function foo(stop) {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" if (stop) return;\n" + // line0 + 3
|
||||
" delete this.a;\n" + // line0 + 4
|
||||
" foo(true);\n" + // line0 + 5
|
||||
"}\n" + // line0 + 6
|
||||
"debugger;\n" + // line1 + 7
|
||||
"foo();\n", // line1 + 8
|
||||
gDebuggee);
|
||||
if (!done) {
|
||||
do_check_true(false);
|
||||
}
|
||||
|
@ -79,10 +79,11 @@ function test_child_breakpoint()
|
||||
});
|
||||
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a, i = 0;\n" + // line0 + 2
|
||||
"for (i = 1; i <= 2; i++) {\n" + // line0 + 3
|
||||
" a = i;\n" + // line0 + 4
|
||||
"}\n"); // line0 + 5
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a, i = 0;\n" + // line0 + 2
|
||||
"for (i = 1; i <= 2; i++) {\n" + // line0 + 3
|
||||
" a = i;\n" + // line0 + 4
|
||||
"}\n", // line0 + 5
|
||||
gDebuggee);
|
||||
}
|
||||
|
@ -80,8 +80,9 @@ function test_child_breakpoint()
|
||||
});
|
||||
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = { b: 1, f: function() { return 2; } };\n" + // line0+2
|
||||
"var res = a.f();\n"); // line0 + 3
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"debugger;\n" + // line0 + 1
|
||||
"var a = { b: 1, f: function() { return 2; } };\n" + // line0+2
|
||||
"var res = a.f();\n", // line0 + 3
|
||||
gDebuggee);
|
||||
}
|
||||
|
@ -55,14 +55,15 @@ function test_child_skip_breakpoint()
|
||||
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"foo();\n"); // line0 + 7
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2
|
||||
" // A comment.\n" + // line0 + 3
|
||||
" this.b = 2;\n" + // line0 + 4
|
||||
"}\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"foo();\n", // line0 + 7
|
||||
gDebuggee);
|
||||
}
|
||||
|
||||
// Set many breakpoints at the same location.
|
||||
|
@ -104,12 +104,13 @@ function test_simple_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2 <-- Breakpoint is set here.
|
||||
"}\n" + // line0 + 3
|
||||
"debugger;\n" + // line0 + 4
|
||||
"foo();\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"var b = 2;\n"); // line0 + 7
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2 <-- Breakpoint is set here.
|
||||
"}\n" + // line0 + 3
|
||||
"debugger;\n" + // line0 + 4
|
||||
"foo();\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"var b = 2;\n", // line0 + 7
|
||||
gDebuggee);
|
||||
}
|
||||
|
@ -102,12 +102,13 @@ function test_simple_breakpoint()
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.eval("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2 <-- Breakpoint is set here.
|
||||
"}\n" + // line0 + 3
|
||||
"debugger;\n" + // line0 + 4
|
||||
"foo();\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"var b = 2;\n"); // line0 + 7
|
||||
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
|
||||
"function foo() {\n" + // line0 + 1
|
||||
" this.a = 1;\n" + // line0 + 2 <-- Breakpoint is set here.
|
||||
"}\n" + // line0 + 3
|
||||
"debugger;\n" + // line0 + 4
|
||||
"foo();\n" + // line0 + 5
|
||||
"debugger;\n" + // line0 + 6
|
||||
"var b = 2;\n", // line0 + 7
|
||||
gDebuggee);
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets-in-gcd-script.js");
|
||||
|
||||
function run_test() {
|
||||
return Task.spawn(function* () {
|
||||
do_test_pending();
|
||||
|
||||
let global = testGlobal("test");
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
Cu.forceGC();
|
||||
|
||||
DebuggerServer.registerModule("xpcshell-test/testactors");
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addTestGlobal(global);
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let tab = yield findTab(client, "test");
|
||||
let [, tabClient] = yield attachTab(client, tab);
|
||||
let [, threadClient] = yield attachThread(tabClient);
|
||||
yield resume(threadClient);
|
||||
|
||||
let source = yield findSource(threadClient, SOURCE_URL);
|
||||
let sourceClient = threadClient.source(source);
|
||||
|
||||
let location = { line: 6, column: 17 };
|
||||
let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
|
||||
do_check_true(packet.isPending);
|
||||
do_check_false("actualLocation" in packet);
|
||||
|
||||
executeSoon(function () {
|
||||
reload(tabClient).then(function () {
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
});
|
||||
});
|
||||
packet = yield waitForPaused(threadClient);
|
||||
do_check_eq(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
do_check_eq(why.type, "breakpoint");
|
||||
do_check_eq(why.actors.length, 1);
|
||||
do_check_eq(why.actors[0], breakpointClient.actor);
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
do_check_eq(where.source.actor, source.actor);
|
||||
do_check_eq(where.line, location.line);
|
||||
do_check_eq(where.column, location.column + 7);
|
||||
let variables = frame.environment.bindings.variables;
|
||||
do_check_eq(variables.a.value, 1);
|
||||
do_check_eq(variables.b.value.type, "undefined");
|
||||
do_check_eq(variables.c.value.type, "undefined");
|
||||
yield resume(threadClient);
|
||||
|
||||
yield close(client);
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets-at-end-of-script.js");
|
||||
|
||||
function run_test() {
|
||||
return Task.spawn(function* () {
|
||||
do_test_pending();
|
||||
|
||||
DebuggerServer.registerModule("xpcshell-test/testactors");
|
||||
DebuggerServer.init(() => true);
|
||||
|
||||
let global = createTestGlobal("test");
|
||||
DebuggerServer.addTestGlobal(global);
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let { tabs } = yield listTabs(client);
|
||||
let tab = findTab(tabs, "test");
|
||||
let [, tabClient] = yield attachTab(client, tab);
|
||||
let [, threadClient] = yield attachThread(tabClient);
|
||||
yield resume(threadClient);
|
||||
|
||||
let promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
let { source } = yield promise;
|
||||
let sourceClient = threadClient.source(source);
|
||||
|
||||
let location = { line: 4, column: 38 };
|
||||
let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
|
||||
do_check_false(packet.isPending);
|
||||
do_check_true("actualLocation" in packet);
|
||||
let actualLocation = packet.actualLocation;
|
||||
do_check_eq(actualLocation.line, 4);
|
||||
do_check_eq(actualLocation.column, 41);
|
||||
|
||||
packet = yield executeOnNextTickAndWaitForPause(function () {
|
||||
Cu.evalInSandbox("f()", global);
|
||||
}, client);
|
||||
do_check_eq(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
do_check_eq(why.type, "breakpoint");
|
||||
do_check_eq(why.actors.length, 1);
|
||||
do_check_eq(why.actors[0], breakpointClient.actor);
|
||||
let where = packet.frame.where;
|
||||
do_check_eq(where.source.actor, source.actor);
|
||||
do_check_eq(where.line, actualLocation.line);
|
||||
do_check_eq(where.column, actualLocation.column);
|
||||
|
||||
yield resume(threadClient);
|
||||
yield close(client);
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets-in-gcd-script.js");
|
||||
|
||||
function run_test() {
|
||||
return Task.spawn(function* () {
|
||||
do_test_pending();
|
||||
|
||||
let global = testGlobal("test");
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
Cu.forceGC(); Cu.forceGC(); Cu.forceGC();
|
||||
|
||||
DebuggerServer.registerModule("xpcshell-test/testactors");
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addTestGlobal(global);
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let { tabs } = yield listTabs(client);
|
||||
let tab = findTab(tabs, "test");
|
||||
let [, tabClient] = yield attachTab(client, tab);
|
||||
let [, threadClient] = yield attachThread(tabClient);
|
||||
yield resume(threadClient);
|
||||
|
||||
let { sources } = yield getSources(threadClient);
|
||||
let source = findSource(sources, SOURCE_URL);
|
||||
let sourceClient = threadClient.source(source);
|
||||
|
||||
let location = { line: 6, column: 17 };
|
||||
let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
|
||||
do_check_true(packet.isPending);
|
||||
do_check_false("actualLocation" in packet);
|
||||
|
||||
packet = yield executeOnNextTickAndWaitForPause(function () {
|
||||
reload(tabClient).then(function () {
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
});
|
||||
}, client);
|
||||
do_check_eq(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
do_check_eq(why.type, "breakpoint");
|
||||
do_check_eq(why.actors.length, 1);
|
||||
do_check_eq(why.actors[0], breakpointClient.actor);
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
do_check_eq(where.source.actor, source.actor);
|
||||
do_check_eq(where.line, location.line);
|
||||
do_check_eq(where.column, 28);
|
||||
let variables = frame.environment.bindings.variables;
|
||||
do_check_eq(variables.a.value, 1);
|
||||
do_check_eq(variables.c.value.type, "undefined");
|
||||
yield resume(threadClient);
|
||||
|
||||
yield close(client);
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var SOURCE_URL = getFileUrl("setBreakpoint-on-column-with-no-offsets.js");
|
||||
|
||||
function run_test() {
|
||||
return Task.spawn(function* () {
|
||||
do_test_pending();
|
||||
|
||||
DebuggerServer.registerModule("xpcshell-test/testactors");
|
||||
DebuggerServer.init(() => true);
|
||||
|
||||
let global = createTestGlobal("test");
|
||||
DebuggerServer.addTestGlobal(global);
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let { tabs } = yield listTabs(client);
|
||||
let tab = findTab(tabs, "test");
|
||||
let [, tabClient] = yield attachTab(client, tab);
|
||||
let [, threadClient] = yield attachThread(tabClient);
|
||||
yield resume(threadClient);
|
||||
|
||||
let promise = waitForNewSource(threadClient, SOURCE_URL);
|
||||
loadSubScript(SOURCE_URL, global);
|
||||
let { source } = yield promise;
|
||||
let sourceClient = threadClient.source(source);
|
||||
|
||||
let location = { line: 4, column: 17 };
|
||||
let [packet, breakpointClient] = yield setBreakpoint(sourceClient, location);
|
||||
do_check_false(packet.isPending);
|
||||
do_check_true("actualLocation" in packet);
|
||||
let actualLocation = packet.actualLocation;
|
||||
do_check_eq(actualLocation.line, 4);
|
||||
do_check_eq(actualLocation.column, 28);
|
||||
|
||||
packet = yield executeOnNextTickAndWaitForPause(function () {
|
||||
Cu.evalInSandbox("f()", global);
|
||||
}, client);
|
||||
do_check_eq(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
do_check_eq(why.type, "breakpoint");
|
||||
do_check_eq(why.actors.length, 1);
|
||||
do_check_eq(why.actors[0], breakpointClient.actor);
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
do_check_eq(where.source.actor, source.actor);
|
||||
do_check_eq(where.line, actualLocation.line);
|
||||
do_check_eq(where.column, actualLocation.column);
|
||||
let variables = frame.environment.bindings.variables;
|
||||
do_check_eq(variables.a.value, 1);
|
||||
do_check_eq(variables.c.value.type, "undefined");
|
||||
|
||||
yield resume(threadClient);
|
||||
yield close(client);
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
@ -27,58 +27,46 @@ function run_test()
|
||||
|
||||
function testBreakpointMapping(aName, aCallback)
|
||||
{
|
||||
// Pause so we can set a breakpoint.
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
do_check_true(!aPacket.error);
|
||||
do_check_eq(aPacket.why.type, "debuggerStatement");
|
||||
Task.spawn(function*() {
|
||||
let response = yield waitForPause(gThreadClient);
|
||||
do_check_eq(response.why.type, "debuggerStatement");
|
||||
|
||||
getSource(gThreadClient, "http://example.com/www/js/" + aName + ".js").then(source => {
|
||||
source.setBreakpoint({
|
||||
// Setting the breakpoint on an empty line so that it is pushed down one
|
||||
// line and we can check the source mapped actualLocation later.
|
||||
line: 3
|
||||
}, function (aResponse) {
|
||||
do_check_true(!aResponse.error);
|
||||
|
||||
// Actual location should come back source mapped still so that
|
||||
// breakpoints are displayed in the UI correctly, etc.
|
||||
do_check_eq(aResponse.actualLocation.line, 4);
|
||||
do_check_eq(aResponse.actualLocation.source.url,
|
||||
"http://example.com/www/js/" + aName + ".js");
|
||||
|
||||
// The eval will cause us to resume, then we get an unsolicited pause
|
||||
// because of our breakpoint, we resume again to finish the eval, and
|
||||
// finally receive our last pause which has the result of the client
|
||||
// evaluation.
|
||||
gThreadClient.eval(null, aName + "()", function (aResponse) {
|
||||
do_check_true(!aResponse.error, "Shouldn't be an error resuming to eval");
|
||||
do_check_eq(aResponse.type, "resumed");
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
do_check_eq(aPacket.why.type, "breakpoint");
|
||||
// Assert that we paused because of the breakpoint at the correct
|
||||
// location in the code by testing that the value of `ret` is still
|
||||
// undefined.
|
||||
do_check_eq(aPacket.frame.environment.bindings.variables.ret.value.type,
|
||||
"undefined");
|
||||
|
||||
gThreadClient.resume(function (aResponse) {
|
||||
do_check_true(!aResponse.error);
|
||||
|
||||
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
|
||||
do_check_eq(aPacket.why.type, "clientEvaluated");
|
||||
do_check_eq(aPacket.why.frameFinished.return, aName);
|
||||
|
||||
gThreadClient.resume(function (aResponse) {
|
||||
do_check_true(!aResponse.error);
|
||||
aCallback();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
const source = yield getSource(gThreadClient, "http://example.com/www/js/" + aName + ".js");
|
||||
response = yield setBreakpoint(source, {
|
||||
// Setting the breakpoint on an empty line so that it is pushed down one
|
||||
// line and we can check the source mapped actualLocation later.
|
||||
line: 3
|
||||
});
|
||||
|
||||
// Should not slide breakpoints for sourcemapped sources
|
||||
do_check_true(!response.actualLocation);
|
||||
|
||||
yield setBreakpoint(source, { line: 4 });
|
||||
|
||||
// The eval will cause us to resume, then we get an unsolicited pause
|
||||
// because of our breakpoint, we resume again to finish the eval, and
|
||||
// finally receive our last pause which has the result of the client
|
||||
// evaluation.
|
||||
response = yield rdpRequest(gThreadClient, gThreadClient.eval, null, aName + "()");
|
||||
do_check_eq(response.type, "resumed");
|
||||
|
||||
response = yield waitForPause(gThreadClient);
|
||||
do_check_eq(response.why.type, "breakpoint");
|
||||
// Assert that we paused because of the breakpoint at the correct
|
||||
// location in the code by testing that the value of `ret` is still
|
||||
// undefined.
|
||||
do_check_eq(response.frame.environment.bindings.variables.ret.value.type,
|
||||
"undefined");
|
||||
|
||||
response = yield resume(gThreadClient);
|
||||
|
||||
response = yield waitForPause(gThreadClient);
|
||||
do_check_eq(response.why.type, "clientEvaluated");
|
||||
do_check_eq(response.why.frameFinished.return, aName);
|
||||
|
||||
response = yield resume(gThreadClient);
|
||||
|
||||
aCallback();
|
||||
});
|
||||
|
||||
gDebuggee.eval("(" + function () {
|
||||
|
@ -256,10 +256,7 @@ skip-if = os != 'linux' || debug || asan
|
||||
reason = bug 1014071
|
||||
[test_setBreakpoint-on-column.js]
|
||||
[test_setBreakpoint-on-column-in-gcd-script.js]
|
||||
[test_setBreakpoint-on-column-with-no-offsets.js]
|
||||
[test_setBreakpoint-on-column-with-no-offsets-at-end-of-line.js]
|
||||
[test_setBreakpoint-on-column-with-no-offsets-at-end-of-script.js]
|
||||
[test_setBreakpoint-on-column-with-no-offsets-in-gcd-script.js]
|
||||
[test_setBreakpoint-on-line.js]
|
||||
[test_setBreakpoint-on-line-in-gcd-script.js]
|
||||
[test_setBreakpoint-on-line-with-multiple-offsets.js]
|
||||
|
Loading…
Reference in New Issue
Block a user