Bug 1543590 - Don't crash trying to fire a dead frame's onPop handler. r=jimb

Mutating Debugger state between the time a callback-triggering event is
reported to js::Debugger::onSomeEventSlowPath and the time the
callback is actually called can invalidate assumptions, and multiple Debuggers
are a way to do that, part 183.

Differential Revision: https://phabricator.services.mozilla.com/D32242

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jason Orendorff 2019-05-31 22:11:33 +00:00
Родитель 21d5c25734
Коммит d5499f2ad6
2 изменённых файлов: 29 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,28 @@
// Don't crash trying to fire a dead frame's onPop handler.
var g = newGlobal({newCompartment: true});
g.eval('function f() { debugger; }');
var log = '';
// Create two Debuggers debugging the same global `g`. Both will put onPop
// handlers on the same frame.
var dbg1 = Debugger(g);
dbg1.onDebuggerStatement = frame1 => {
frame1.onPop = completion => {
log += 'A';
dbg2.removeDebuggee(g); // kills frame2, so frame2.onPop should not fire
log += 'B';
};
};
var dbg2 = Debugger(g);
dbg2.onDebuggerStatement = frame2 => {
frame2.onPop = completion => {
log += 'C';
};
};
g.f();
assertEq(log, 'AB');

Просмотреть файл

@ -1054,7 +1054,7 @@ bool Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame,
Debugger* dbg = Debugger::fromChildJSObject(frameobj); Debugger* dbg = Debugger::fromChildJSObject(frameobj);
EnterDebuggeeNoExecute nx(cx, *dbg, adjqi); EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
if (dbg->enabled && frameobj->onPopHandler()) { if (dbg->enabled && frameobj->isLive() && frameobj->onPopHandler()) {
OnPopHandler* handler = frameobj->onPopHandler(); OnPopHandler* handler = frameobj->onPopHandler();
Maybe<AutoRealm> ar; Maybe<AutoRealm> ar;