Bug 1251919 - Nuke Debugger wrappers on failure. (r=shu)

This commit is contained in:
Eric Faust 2016-05-03 03:55:14 -07:00
parent 14c8099671
commit 1fa29f409e
3 changed files with 43 additions and 10 deletions

View File

@ -0,0 +1,13 @@
// |jit-test| error: out of memory
if (!('oomTest' in this))
throw new Error("out of memory");
// jsfunfuzz-generated
fullcompartmentchecks(true);
// Adapted from randomly chosen test: js/src/jit-test/tests/debug/bug-1248162.js
var dbg = new Debugger;
dbg.onNewGlobalObject = function() {};
oomTest(function() {
newGlobal();
})

View File

@ -398,6 +398,14 @@ Debugger::slowPathCheckNoExecute(JSContext* cx, HandleScript script)
return EnterDebuggeeNoExecute::reportIfFoundInStack(cx, script);
}
static inline void
NukeDebuggerWrapper(NativeObject *wrapper)
{
// In some OOM failure cases, we need to destroy the edge to the referent,
// to avoid trying to trace it during untimely collections.
wrapper->setPrivate(nullptr);
}
/*** Breakpoints *********************************************************************************/
@ -934,14 +942,19 @@ Debugger::wrapEnvironment(JSContext* cx, Handle<Env*> env, MutableHandleValue rv
return false;
envobj->setPrivateGCThing(env);
envobj->setReservedSlot(JSSLOT_DEBUGENV_OWNER, ObjectValue(*object));
if (!p.add(cx, environments, env, envobj))
if (!p.add(cx, environments, env, envobj)) {
NukeDebuggerWrapper(envobj);
return false;
}
CrossCompartmentKey key(CrossCompartmentKey::DebuggerEnvironment, object, env);
if (!object->compartment()->putWrapper(cx, key, ObjectValue(*envobj))) {
NukeDebuggerWrapper(envobj);
environments.remove(env);
return false;
}
}
rval.setObject(*envobj);
return true;
@ -976,12 +989,15 @@ Debugger::wrapDebuggeeValue(JSContext* cx, MutableHandleValue vp)
dobj->setPrivateGCThing(obj);
dobj->setReservedSlot(JSSLOT_DEBUGOBJECT_OWNER, ObjectValue(*object));
if (!p.add(cx, objects, obj, dobj))
if (!p.add(cx, objects, obj, dobj)) {
NukeDebuggerWrapper(dobj);
return false;
}
if (obj->compartment() != object->compartment()) {
CrossCompartmentKey key(CrossCompartmentKey::DebuggerObject, object, obj);
if (!object->compartment()->putWrapper(cx, key, ObjectValue(*dobj))) {
NukeDebuggerWrapper(dobj);
objects.remove(obj);
ReportOutOfMemory(cx);
return false;
@ -5029,7 +5045,7 @@ class DebuggerScriptSetPrivateMatcher
ReturnType match(Handle<WasmModuleObject*> module) { obj_->setPrivateGCThing(module); }
};
JSObject*
NativeObject*
Debugger::newDebuggerScript(JSContext* cx, Handle<DebuggerScriptReferent> referent)
{
assertSameCompartment(cx, object.get());
@ -5059,19 +5075,23 @@ Debugger::wrapVariantReferent(JSContext* cx, Map& map, CrossCompartmentKey::Kind
DependentAddPtr<Map> p(cx, map, untaggedReferent);
if (!p) {
JSObject* wrapper = newVariantWrapper(cx, referent);
NativeObject* wrapper = newVariantWrapper(cx, referent);
if (!wrapper)
return nullptr;
if (!p.add(cx, map, untaggedReferent, wrapper))
if (!p.add(cx, map, untaggedReferent, wrapper)) {
NukeDebuggerWrapper(wrapper);
return nullptr;
}
CrossCompartmentKey key(keyKind, object, untaggedReferent);
if (!object->compartment()->putWrapper(cx, key, ObjectValue(*wrapper))) {
NukeDebuggerWrapper(wrapper);
map.remove(untaggedReferent);
ReportOutOfMemory(cx);
return nullptr;
}
}
return p->value();
@ -6301,7 +6321,7 @@ class SetDebuggerSourcePrivateMatcher
ReturnType match(Handle<WasmModuleObject*> module) { obj_->setPrivateGCThing(module); }
};
JSObject*
NativeObject*
Debugger::newDebuggerSource(JSContext* cx, Handle<DebuggerSourceReferent> referent)
{
assertSameCompartment(cx, object.get());

View File

@ -690,10 +690,10 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
JSTrapStatus fireNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global, MutableHandleValue vp);
JSTrapStatus firePromiseHook(JSContext* cx, Hook hook, HandleObject promise, MutableHandleValue vp);
JSObject* newVariantWrapper(JSContext* cx, Handle<DebuggerScriptReferent> referent) {
NativeObject* newVariantWrapper(JSContext* cx, Handle<DebuggerScriptReferent> referent) {
return newDebuggerScript(cx, referent);
}
JSObject* newVariantWrapper(JSContext* cx, Handle<DebuggerSourceReferent> referent) {
NativeObject* newVariantWrapper(JSContext* cx, Handle<DebuggerSourceReferent> referent) {
return newDebuggerSource(cx, referent);
}
@ -715,13 +715,13 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
* Allocate and initialize a Debugger.Script instance whose referent is
* |referent|.
*/
JSObject* newDebuggerScript(JSContext* cx, Handle<DebuggerScriptReferent> referent);
NativeObject* newDebuggerScript(JSContext* cx, Handle<DebuggerScriptReferent> referent);
/*
* Allocate and initialize a Debugger.Source instance whose referent is
* |referent|.
*/
JSObject* newDebuggerSource(JSContext* cx, Handle<DebuggerSourceReferent> referent);
NativeObject* newDebuggerSource(JSContext* cx, Handle<DebuggerSourceReferent> referent);
/*
* Receive a "new script" event from the engine. A new script was compiled