Assertion failure: cx->realm()->isDebuggee()
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
People
(Reporter: anbu1024.me, Unassigned)
References
(Blocks 1 open bug)
Details
Steps to reproduce:
SpiderMonkey version:
commit 920be8b5eee004fc10a2785fab49b860be4d4ba3
SpiderMonkey build cmd:
/bin/sh ../../gecko-dev/js/src/configure --enable-debug --disable-optimize --disable-shared-js --disable-tests
Exec:
./js ./test.js
Test Case:
for (let a = 8, b = 10;
(() => {
const x = a < b;
this.newGlobal(a, this, b, x);
return x;
})();
(() => {b--;})()
)
{}
async function foo(a) {
return a;
}
const x = foo().then(foo);
for (let i = 0, j = 10; i !== j;
(() => {
function zoo(a) {
async function* bob() {
return a;
}
bob().next();
}
new zoo(x);
j--;
})()) {
}
const v88 = this.Debugger;
const y = this.wasmIntrinsicI8VecMul(foo, this);
function alice() {
const tom = v88();
for (let i = 0, j = 10;
(() => {
return y in arguments;
})();
) {
}
return tom.findAllGlobals(x, tom);
}
Object.defineProperty(y, "constructor", { writable: true, configurable: true, value: alice });
const z = y.constructor;
z()[1].makeDebuggeeValue(x).getPromiseReactions();
Actual results:
Error msg:
Assertion failure: cx->realm()->isDebuggee(), at gecko-dev/js/src/debugger/DebugScript.cpp:305
Comment 1•2 years ago
|
||
Thank you for reporting!
Here's reduced testcase:
var p = new Promise(_ => {});
async function f() {
await p;
}
f();
const dbg = new Debugger();
const globals = dbg.findAllGlobals();
const g = globals[0];
const q = g.makeDebuggeeValue(p);
q.getPromiseReactions();
So, what's happening here is that, Debugger().findAllGlobals()
returns the current global, which is not debuggee, wrapped by Debugger.Object
.
But getPromiseReactions
assumes the wrapped value belongs to debuggee global.
This is because, the globals returned by findAllGlobals
are supposed to be either added to debugger immediately with addDebuggee
, or the reference gets discarded.
In tree, findAllGlobals
is called only in the following places:
this.makeDebugger = makeDebugger.bind(null, {
findDebuggees: dbg => dbg.findAllGlobals(),
this.makeDebugger = makeDebugger.bind(null, {
findDebuggees: dbg => dbg.findAllGlobals(),
this.makeDebugger = makeDebugger.bind(null, {
findDebuggees: dbg => {
return dbg.findAllGlobals().filter(this._shouldAddNewGlobalAsDebuggee);
and globals returned there are immediately passed to addDebuggee
.
So the case doesn't happen.
module.exports = function makeDebugger({
findDebuggees,
shouldAddNewGlobalAsDebuggee,
} = {}) {
...
for (const global of findDebuggees(this)) {
safeAddDebuggee(this, global);
...
function safeAddDebuggee(dbg, global) {
let globalDO;
try {
globalDO = dbg.addDebuggee(global);
} catch (e) {
// Ignoring attempt to add the debugger's compartment as a debuggee.
return;
Also, given Debugger
is not exposed to web content, this issue is shell-only.
Updated•2 years ago
|
Description
•