Bug 885388 - Introduce a mechanism to make certain globals invisible to the debugger. r=jimb

This commit is contained in:
Bobby Holley 2013-08-01 18:38:45 -07:00
parent c83fb7ad69
commit e964ea9e66
3 changed files with 24 additions and 2 deletions

View File

@ -313,7 +313,7 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change ob
MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})")
MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data")
MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object")
MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "")
MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 263, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee")
MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version")
MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object")
MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")

View File

@ -3223,9 +3223,11 @@ SameZoneAs(JSObject *obj)
struct JS_PUBLIC_API(CompartmentOptions) {
ZoneSpecifier zoneSpec;
JSVersion version;
bool invisibleToDebugger;
explicit CompartmentOptions() : zoneSpec(JS::FreshZone)
, version(JSVERSION_UNKNOWN)
, invisibleToDebugger(false)
{}
CompartmentOptions &setZone(ZoneSpecifier spec) { zoneSpec = spec; return *this; }
@ -3234,6 +3236,15 @@ struct JS_PUBLIC_API(CompartmentOptions) {
version = version_;
return *this;
}
// Certain scopes (i.e. XBL compilation scopes) are implementation details
// of the embedding, and references to them should never leak out to script.
// This flag causes the this compartment to skip firing onNewGlobalObject
// and makes addDebuggee a no-op for this global.
CompartmentOptions &setInvisibleToDebugger(bool invisible) {
invisibleToDebugger = invisible;
return *this;
}
};
} /* namespace JS */

View File

@ -1339,6 +1339,8 @@ void
Debugger::slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global)
{
JS_ASSERT(!JS_CLIST_IS_EMPTY(&cx->runtime()->onNewGlobalObjectWatchers));
if (global->compartment()->options().invisibleToDebugger)
return;
/*
* Make a copy of the runtime's onNewGlobalObjectWatchers before running the
@ -1958,7 +1960,7 @@ Debugger::addAllGlobalsAsDebuggees(JSContext *cx, unsigned argc, Value *vp)
THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg);
AutoDebugModeGC dmgc(cx->runtime());
for (CompartmentsIter c(cx->runtime()); !c.done(); c.next()) {
if (c == dbg->object->compartment())
if (c == dbg->object->compartment() || c->options().invisibleToDebugger)
continue;
c->zone()->scheduledForDestruction = false;
GlobalObject *global = c->maybeGlobal();
@ -2134,7 +2136,16 @@ Debugger::addDebuggeeGlobal(JSContext *cx,
if (debuggees.has(global))
return true;
// Callers should generally be unable to get a reference to a debugger-
// invisible global in order to pass it to addDebuggee. But this is possible
// with certain testing aides we expose in the shell, so just make addDebuggee
// throw in that case.
JSCompartment *debuggeeCompartment = global->compartment();
if (debuggeeCompartment->options().invisibleToDebugger) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_DEBUG_CANT_DEBUG_GLOBAL);
return false;
}
/*
* Check for cycles. If global's compartment is reachable from this