Source code

Revision control

Copy as Markdown

Other Tools

// Test that multiple debuggers with separate debuggees can toggle
// collectCoverageInfo independently without blocking each other.
var g1 = newGlobal({ newCompartment: true });
var g2 = newGlobal({ newCompartment: true });
var g3 = newGlobal({ newCompartment: true });
// Create two separate debuggers
var dbg1 = new Debugger();
var dbg2 = new Debugger();
// dbg1 debugs g1, dbg2 debugs g2, g3 is not debugged
dbg1.addDebuggee(g1);
dbg2.addDebuggee(g2);
// Set up interleaved call chain: g1 -> g2 -> g3
g1.g2 = g2;
g2.g3 = g3;
g1.evaluate(`
function func1() {
return g2.func2();
}
`);
g2.evaluate(`
function func2() {
return g3.func3();
}
`);
g3.evaluate(`
function func3() {
debugger;
return 42;
}
`);
// Test 1: dbg1 cannot toggle coverage when its debuggee (g1) is on the stack
var dbg1ToggleAttempted = false;
dbg1.onDebuggerStatement = function() {
// Stack: g3.func3 (not debugged) -> g2.func2 (dbg2's debuggee) -> g1.func1 (dbg1's debuggee)
var caught = false;
try {
dbg1.collectCoverageInfo = true;
dbg1ToggleAttempted = true;
} catch (e) {
caught = true;
assertEq(e.message, "can't start debugging: a debuggee script is on the stack");
}
assertEq(caught, true);
assertEq(dbg1ToggleAttempted, false);
};
// dbg2 should also not be able to toggle when its debuggee (g2) is on the stack
var dbg2ToggleAttempted = false;
dbg2.onDebuggerStatement = function() {
// Stack: g3.func3 (not debugged) -> g2.func2 (dbg2's debuggee) -> g1.func1 (dbg1's debuggee)
var caught = false;
try {
dbg2.collectCoverageInfo = true;
dbg2ToggleAttempted = true;
} catch (e) {
caught = true;
assertEq(e.message, "can't start debugging: a debuggee script is on the stack");
}
assertEq(caught, true);
assertEq(dbg2ToggleAttempted, false);
};
g1.func1();
dbg1.onDebuggerStatement = undefined;
dbg2.onDebuggerStatement = undefined;
// Test 2: dbg1 can toggle coverage when only dbg2's debuggee is on the stack
g2.dbg1 = dbg1;
g2.evaluate(`
function testDbg1Toggle() {
// At this point only g2 is on the stack, which is dbg2's debuggee but not dbg1's
// So dbg1 should be able to toggle its coverage
dbg1.collectCoverageInfo = true;
dbg1.collectCoverageInfo = false;
dbg1.collectCoverageInfo = true;
}
`);
g2.testDbg1Toggle();
// Test 3: dbg2 can toggle coverage when only dbg1's debuggee is on the stack
g1.dbg2 = dbg2;
g1.evaluate(`
function testDbg2Toggle() {
// At this point only g1 is on the stack, which is dbg1's debuggee but not dbg2's
// So dbg2 should be able to toggle its coverage
dbg2.collectCoverageInfo = true;
dbg2.collectCoverageInfo = false;
dbg2.collectCoverageInfo = true;
}
`);
g1.testDbg2Toggle();
// Test 4: Both debuggers can toggle when g3 (neither's debuggee) is on the stack
g3.dbg1 = dbg1;
g3.dbg2 = dbg2;
g3.evaluate(`
function testBothToggle() {
// At this point only g3 is on the stack, which is not a debuggee of either debugger
// So both debuggers should be able to toggle their coverage
dbg1.collectCoverageInfo = false;
dbg2.collectCoverageInfo = false;
dbg1.collectCoverageInfo = true;
dbg2.collectCoverageInfo = true;
dbg1.collectCoverageInfo = false;
dbg2.collectCoverageInfo = false;
}
`);
g3.testBothToggle();
// Test 5: Complex scenario - dbg1's debuggee calls dbg2's debuggee
// Create a new call chain for clearer testing
g1.evaluate(`
function func1b() {
return g2.func2b();
}
`);
g2.evaluate(`
function func2b() {
debugger;
return 100;
}
`);
dbg1.collectCoverageInfo = true;
dbg2.collectCoverageInfo = true;
var dbg1DisableAttempted = false;
var dbg2DisableAttempted = false;
dbg1.onDebuggerStatement = function() {
// Stack: g2.func2b (dbg2's debuggee) -> g1.func1b (dbg1's debuggee)
// dbg1 cannot toggle because g1.func1b is on the stack
var caught = false;
try {
dbg1.collectCoverageInfo = false;
dbg1DisableAttempted = true;
} catch (e) {
caught = true;
assertEq(e.message, "can't start debugging: a debuggee script is on the stack");
}
assertEq(caught, true);
assertEq(dbg1DisableAttempted, false);
};
dbg2.onDebuggerStatement = function() {
// Stack: g2.func2b (dbg2's debuggee) -> g1.func1b (dbg1's debuggee)
// dbg2 cannot toggle because g2.func2b is on the stack
var caught = false;
try {
dbg2.collectCoverageInfo = false;
dbg2DisableAttempted = true;
} catch (e) {
caught = true;
assertEq(e.message, "can't start debugging: a debuggee script is on the stack");
}
assertEq(caught, true);
assertEq(dbg2DisableAttempted, false);
};
g1.func1b();
// Clean up
dbg1.onDebuggerStatement = undefined;
dbg2.onDebuggerStatement = undefined;
dbg1.collectCoverageInfo = false;
dbg2.collectCoverageInfo = false;