mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Backed out changeset 2c5e99c6de6a (bug 1564168) for causing bustages in Debugger-enabled-01.binjs CLOSED TREE
This commit is contained in:
parent
32ebfab7db
commit
8f73896852
@ -34,5 +34,5 @@ function run_test()
|
||||
g.stopMe(doc.createEvent("MouseEvent"));
|
||||
} + ")()");
|
||||
|
||||
dbg.removeAllDebuggees();
|
||||
dbg.enabled = false;
|
||||
}
|
||||
|
@ -316,7 +316,9 @@ Breakpoint::Breakpoint(Debugger* debugger, BreakpointSite* site,
|
||||
|
||||
void Breakpoint::destroy(FreeOp* fop,
|
||||
MayDestroySite mayDestroySite /* true */) {
|
||||
site->dec(fop);
|
||||
if (debugger->enabled) {
|
||||
site->dec(fop);
|
||||
}
|
||||
debugger->breakpoints.remove(this);
|
||||
site->breakpoints.remove(this);
|
||||
gc::Cell* cell = site->owningCellUnbarriered();
|
||||
@ -371,6 +373,7 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
|
||||
: object(dbg),
|
||||
debuggees(cx->zone()),
|
||||
uncaughtExceptionHook(nullptr),
|
||||
enabled(true),
|
||||
allowUnobservedAsmJS(false),
|
||||
collectCoverageInfo(false),
|
||||
observedGCs(cx->zone()),
|
||||
@ -623,8 +626,8 @@ static bool DebuggerExists(GlobalObject* global,
|
||||
/* static */
|
||||
bool Debugger::hasLiveHook(GlobalObject* global, Hook which) {
|
||||
return DebuggerExists(global, [=](Debugger* dbg) {
|
||||
return dbg->getHook(which);
|
||||
});
|
||||
return dbg->enabled && dbg->getHook(which);
|
||||
});
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -665,6 +668,10 @@ JSObject* Debugger::getHook(Hook hook) const {
|
||||
}
|
||||
|
||||
bool Debugger::hasAnyLiveHooks(JSRuntime* rt) const {
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A onNewGlobalObject hook does not hold its Debugger live, so its behavior
|
||||
// is nondeterministic. This behavior is not satisfying, but it is at least
|
||||
// documented.
|
||||
@ -903,7 +910,7 @@ bool DebugAPI::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame,
|
||||
Debugger* dbg = Debugger::fromChildJSObject(frameobj);
|
||||
EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
|
||||
|
||||
if (frameobj->isLive() && frameobj->onPopHandler()) {
|
||||
if (dbg->enabled && frameobj->isLive() && frameobj->onPopHandler()) {
|
||||
OnPopHandler* handler = frameobj->onPopHandler();
|
||||
|
||||
Maybe<AutoRealm> ar;
|
||||
@ -2193,7 +2200,7 @@ ResumeMode Debugger::dispatchHook(JSContext* cx, HookIsEnabledFun hookIsEnabled,
|
||||
if (GlobalObject::DebuggerVector* debuggers = global->getDebuggers()) {
|
||||
for (auto p = debuggers->begin(); p != debuggers->end(); p++) {
|
||||
Debugger* dbg = *p;
|
||||
if (hookIsEnabled(dbg)) {
|
||||
if (dbg->enabled && hookIsEnabled(dbg)) {
|
||||
if (!triggered.append(ObjectValue(*dbg->toJSObject()))) {
|
||||
return ResumeMode::Terminate;
|
||||
}
|
||||
@ -2214,7 +2221,7 @@ ResumeMode Debugger::dispatchHook(JSContext* cx, HookIsEnabledFun hookIsEnabled,
|
||||
for (Value* p = triggered.begin(); p != triggered.end(); p++) {
|
||||
Debugger* dbg = Debugger::fromJSObject(&p->toObject());
|
||||
EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
|
||||
if (dbg->debuggees.has(global) && hookIsEnabled(dbg)) {
|
||||
if (dbg->debuggees.has(global) && dbg->enabled && hookIsEnabled(dbg)) {
|
||||
ResumeMode resumeMode = fireHook(dbg);
|
||||
adjqi.runJobs();
|
||||
if (resumeMode != ResumeMode::Continue) {
|
||||
@ -2326,8 +2333,8 @@ ResumeMode DebugAPI::onTrap(JSContext* cx, MutableHandleValue vp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// There are two reasons we have to check whether dbg is debugging
|
||||
// global.
|
||||
// There are two reasons we have to check whether dbg is enabled and
|
||||
// debugging global.
|
||||
//
|
||||
// One is just that one breakpoint handler can disable other Debuggers
|
||||
// or remove debuggees.
|
||||
@ -2336,7 +2343,8 @@ ResumeMode DebugAPI::onTrap(JSContext* cx, MutableHandleValue vp) {
|
||||
// specific global--until they are executed. Only now do we know which
|
||||
// global the script is running against.
|
||||
Debugger* dbg = bp->debugger;
|
||||
if (dbg->debuggees.has(global)) {
|
||||
bool hasDebuggee = dbg->enabled && dbg->debuggees.has(global);
|
||||
if (hasDebuggee) {
|
||||
Maybe<AutoRealm> ar;
|
||||
ar.emplace(cx, dbg->object);
|
||||
EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
|
||||
@ -2635,7 +2643,7 @@ Maybe<double> DebugAPI::allocationSamplingProbability(GlobalObject* global) {
|
||||
// this is safe as long as dbgp does not escape.
|
||||
Debugger* dbgp = p->unbarrieredGet();
|
||||
|
||||
if (dbgp->trackingAllocationSites) {
|
||||
if (dbgp->trackingAllocationSites && dbgp->enabled) {
|
||||
foundAnyDebuggers = true;
|
||||
probability = std::max(dbgp->allocationSamplingProbability, probability);
|
||||
}
|
||||
@ -2671,7 +2679,7 @@ bool DebugAPI::slowPathOnLogAllocationSite(JSContext* cx, HandleObject obj,
|
||||
// such that the vector gets reallocated.
|
||||
MOZ_ASSERT(dbgs.begin() == begin);
|
||||
|
||||
if ((*dbgp)->trackingAllocationSites &&
|
||||
if ((*dbgp)->trackingAllocationSites && (*dbgp)->enabled &&
|
||||
!(*dbgp)->appendAllocationSite(cx, obj, frame, when)) {
|
||||
return false;
|
||||
}
|
||||
@ -2689,7 +2697,7 @@ bool Debugger::isDebuggeeUnbarriered(const Realm* realm) const {
|
||||
bool Debugger::appendAllocationSite(JSContext* cx, HandleObject obj,
|
||||
HandleSavedFrame frame,
|
||||
mozilla::TimeStamp when) {
|
||||
MOZ_ASSERT(trackingAllocationSites);
|
||||
MOZ_ASSERT(trackingAllocationSites && enabled);
|
||||
|
||||
AutoRealm ar(cx, object);
|
||||
RootedObject wrappedFrame(cx, frame);
|
||||
@ -3216,21 +3224,21 @@ bool Debugger::hookObservesAllExecution(Hook which) {
|
||||
}
|
||||
|
||||
Debugger::IsObserving Debugger::observesAllExecution() const {
|
||||
if (!!getHook(OnEnterFrame)) {
|
||||
if (enabled && !!getHook(OnEnterFrame)) {
|
||||
return Observing;
|
||||
}
|
||||
return NotObserving;
|
||||
}
|
||||
|
||||
Debugger::IsObserving Debugger::observesAsmJS() const {
|
||||
if (!allowUnobservedAsmJS) {
|
||||
if (enabled && !allowUnobservedAsmJS) {
|
||||
return Observing;
|
||||
}
|
||||
return NotObserving;
|
||||
}
|
||||
|
||||
Debugger::IsObserving Debugger::observesCoverage() const {
|
||||
if (collectCoverageInfo) {
|
||||
if (enabled && collectCoverageInfo) {
|
||||
return Observing;
|
||||
}
|
||||
return NotObserving;
|
||||
@ -3347,7 +3355,7 @@ bool DebugAPI::isObservedByDebuggerTrackingAllocations(
|
||||
// Use unbarrieredGet() to prevent triggering read barrier while
|
||||
// collecting, this is safe as long as dbg does not escape.
|
||||
Debugger* dbg = p->unbarrieredGet();
|
||||
if (dbg->trackingAllocationSites) {
|
||||
if (dbg->trackingAllocationSites && dbg->enabled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -3754,6 +3762,71 @@ static Debugger* Debugger_fromThisValue(JSContext* cx, const CallArgs& args,
|
||||
Debugger* dbg = Debugger_fromThisValue(cx, args, fnname); \
|
||||
if (!dbg) return false
|
||||
|
||||
/* static */
|
||||
bool Debugger::getEnabled(JSContext* cx, unsigned argc, Value* vp) {
|
||||
THIS_DEBUGGER(cx, argc, vp, "get enabled", args, dbg);
|
||||
args.rval().setBoolean(dbg->enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool Debugger::setEnabled(JSContext* cx, unsigned argc, Value* vp) {
|
||||
THIS_DEBUGGER(cx, argc, vp, "set enabled", args, dbg);
|
||||
if (!args.requireAtLeast(cx, "Debugger.set enabled", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wasEnabled = dbg->enabled;
|
||||
dbg->enabled = ToBoolean(args[0]);
|
||||
|
||||
if (wasEnabled != dbg->enabled) {
|
||||
if (dbg->trackingAllocationSites) {
|
||||
if (wasEnabled) {
|
||||
dbg->removeAllocationsTrackingForAllDebuggees();
|
||||
} else {
|
||||
if (!dbg->addAllocationsTrackingForAllDebuggees(cx)) {
|
||||
dbg->enabled = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Breakpoint* bp = dbg->firstBreakpoint(); bp;
|
||||
bp = bp->nextInDebugger()) {
|
||||
if (!wasEnabled) {
|
||||
bp->site->inc(cx->runtime()->defaultFreeOp());
|
||||
} else {
|
||||
bp->site->dec(cx->runtime()->defaultFreeOp());
|
||||
}
|
||||
}
|
||||
|
||||
// Add or remove ourselves from the runtime's list of Debuggers
|
||||
// that care about new globals.
|
||||
if (dbg->getHook(OnNewGlobalObject)) {
|
||||
if (!wasEnabled) {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().pushBack(dbg);
|
||||
} else {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().remove(dbg);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the compartment is observable if we are re-enabling a
|
||||
// Debugger with hooks that observe all execution.
|
||||
if (!dbg->updateObservesAllExecutionOnDebuggees(
|
||||
cx, dbg->observesAllExecution())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: To toogle code coverage, we currently need to have no live
|
||||
// stack frame, thus the coverage does not depend on the enabled flag.
|
||||
|
||||
dbg->updateObservesAsmJSOnDebuggees(dbg->observesAsmJS());
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool Debugger::getHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg,
|
||||
Hook which) {
|
||||
@ -3881,11 +3954,13 @@ bool Debugger::setOnNewGlobalObject(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
||||
// Add or remove ourselves from the runtime's list of Debuggers that care
|
||||
// about new globals.
|
||||
JSObject* newHook = dbg->getHook(OnNewGlobalObject);
|
||||
if (!oldHook && newHook) {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().pushBack(dbg);
|
||||
} else if (oldHook && !newHook) {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().remove(dbg);
|
||||
if (dbg->enabled) {
|
||||
JSObject* newHook = dbg->getHook(OnNewGlobalObject);
|
||||
if (!oldHook && newHook) {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().pushBack(dbg);
|
||||
} else if (oldHook && !newHook) {
|
||||
cx->runtime()->onNewGlobalObjectWatchers().remove(dbg);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -4413,13 +4488,13 @@ bool Debugger::addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
});
|
||||
|
||||
// (5)
|
||||
if (trackingAllocationSites &&
|
||||
if (trackingAllocationSites && enabled &&
|
||||
!Debugger::addAllocationsTracking(cx, global)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto allocationsTrackingGuard = MakeScopeExit([&] {
|
||||
if (trackingAllocationSites) {
|
||||
if (trackingAllocationSites && enabled) {
|
||||
Debugger::removeAllocationsTracking(*global);
|
||||
}
|
||||
});
|
||||
@ -5846,6 +5921,7 @@ bool Debugger::adoptSource(JSContext* cx, unsigned argc, Value* vp) {
|
||||
}
|
||||
|
||||
const JSPropertySpec Debugger::properties[] = {
|
||||
JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
|
||||
JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
|
||||
Debugger::setOnDebuggerStatement, 0),
|
||||
JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
|
||||
@ -6038,13 +6114,16 @@ bool Debugger::observesFrame(const FrameIter& iter) const {
|
||||
}
|
||||
|
||||
bool Debugger::observesScript(JSScript* script) const {
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
// Don't ever observe self-hosted scripts: the Debugger API can break
|
||||
// self-hosted invariants.
|
||||
return observesGlobal(&script->global()) && !script->selfHosted();
|
||||
}
|
||||
|
||||
bool Debugger::observesWasm(wasm::Instance* instance) const {
|
||||
if (!instance->debugEnabled()) {
|
||||
if (!enabled || !instance->debugEnabled()) {
|
||||
return false;
|
||||
}
|
||||
return observesGlobal(&instance->object()->global());
|
||||
@ -7157,7 +7236,7 @@ JS_PUBLIC_API bool FireOnGarbageCollectionHookRequired(JSContext* cx) {
|
||||
AutoCheckCannotGC noGC;
|
||||
|
||||
for (Debugger* dbg : cx->runtime()->debuggerList()) {
|
||||
if (dbg->observedGC(cx->runtime()->gc.majorGCCount()) &&
|
||||
if (dbg->enabled && dbg->observedGC(cx->runtime()->gc.majorGCCount()) &&
|
||||
dbg->getHook(Debugger::OnGarbageCollection)) {
|
||||
return true;
|
||||
}
|
||||
@ -7177,7 +7256,7 @@ JS_PUBLIC_API bool FireOnGarbageCollectionHook(
|
||||
AutoCheckCannotGC noGC;
|
||||
|
||||
for (Debugger* dbg : cx->runtime()->debuggerList()) {
|
||||
if (dbg->observedGC(data->majorGCNumber()) &&
|
||||
if (dbg->enabled && dbg->observedGC(data->majorGCNumber()) &&
|
||||
dbg->getHook(Debugger::OnGarbageCollection)) {
|
||||
if (!triggered.append(dbg->object)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
|
@ -243,8 +243,8 @@ extern void CheckDebuggeeThing(JSObject* obj, bool invisibleOk);
|
||||
* not, because they are not deleted when a compartment is no longer a
|
||||
* debuggee: the values need to maintain object identity across add/remove/add
|
||||
* transitions. (Frames are an exception to the rule. Existing Debugger.Frame
|
||||
* objects are killed if their realm is removed as a debugger; if the realm
|
||||
* beacomes a debuggee again later, new Frame objects are created.)
|
||||
* objects are killed when debugging is disabled for their compartment, and if
|
||||
* it's re-enabled later, new Frame objects are created.)
|
||||
*/
|
||||
template <class UnbarrieredKey, bool InvisibleKeysOk = false>
|
||||
class DebuggerWeakMap
|
||||
@ -445,6 +445,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
return observedGCs.put(majorGCNumber);
|
||||
}
|
||||
|
||||
bool isEnabled() const { return enabled; }
|
||||
|
||||
static SavedFrame* getObjectAllocationSite(JSObject& obj);
|
||||
|
||||
struct AllocationsLogEntry {
|
||||
@ -490,6 +492,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
debuggees; /* Debuggee globals. Cross-compartment weak references. */
|
||||
JS::ZoneSet debuggeeZones; /* Set of zones that we have debuggees in. */
|
||||
js::GCPtrObject uncaughtExceptionHook; /* Strong reference. */
|
||||
bool enabled;
|
||||
bool allowUnobservedAsmJS;
|
||||
|
||||
// Whether to enable code coverage on the Debuggee.
|
||||
@ -543,7 +546,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
/*
|
||||
* Add allocations tracking for objects allocated within the given
|
||||
* debuggee's compartment. The given debuggee global must be observed by at
|
||||
* least one Debugger that is tracking allocations.
|
||||
* least one Debugger that is enabled and tracking allocations.
|
||||
*/
|
||||
static MOZ_MUST_USE bool addAllocationsTracking(
|
||||
JSContext* cx, Handle<GlobalObject*> debuggee);
|
||||
@ -562,7 +565,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
void removeAllocationsTrackingForAllDebuggees();
|
||||
|
||||
/*
|
||||
* If this Debugger has a onNewGlobalObject handler, then
|
||||
* If this Debugger is enabled, and has a onNewGlobalObject handler, then
|
||||
* this link is inserted into the list headed by
|
||||
* JSRuntime::onNewGlobalObjectWatchers.
|
||||
*/
|
||||
@ -599,10 +602,9 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
* onEnterFrame handler on resume, and to retain onStep and onPop hooks.
|
||||
*
|
||||
* An entry is present in this table when:
|
||||
* - both the debuggee generator object and the Debugger.Frame object exists
|
||||
* - the debuggee generator object belongs to a relam that is a debuggee of
|
||||
* the Debugger.Frame's owner.
|
||||
*
|
||||
* - both the debuggee generator object and the Debugger.Frame object exist
|
||||
* - the Debugger.Frame's owner is still an enabled debugger of
|
||||
* the debuggee compartment
|
||||
* regardless of whether the frame is currently suspended. (This list is
|
||||
* meant to explain why we update the table in the particular places where
|
||||
* we do so.)
|
||||
@ -773,6 +775,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||
static MOZ_MUST_USE bool setHookImpl(JSContext* cx, CallArgs& args,
|
||||
Debugger& dbg, Hook which);
|
||||
|
||||
static bool getEnabled(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool setEnabled(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool getOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool setOnDebuggerStatement(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool getOnExceptionUnwind(JSContext* cx, unsigned argc, Value* vp);
|
||||
@ -1225,7 +1229,7 @@ class BreakpointSite {
|
||||
* site's list.
|
||||
*
|
||||
* GC rules:
|
||||
* - script is live and breakpoint exists
|
||||
* - script is live, breakpoint exists, and debugger is enabled
|
||||
* ==> debugger is live
|
||||
* - script is live, breakpoint exists, and debugger is live
|
||||
* ==> retain the breakpoint and the handler object is live
|
||||
@ -1344,12 +1348,16 @@ js::GCPtrNativeObject& Debugger::toJSObjectRef() {
|
||||
return object;
|
||||
}
|
||||
|
||||
bool Debugger::observesEnterFrame() const { return getHook(OnEnterFrame); }
|
||||
bool Debugger::observesEnterFrame() const {
|
||||
return enabled && getHook(OnEnterFrame);
|
||||
}
|
||||
|
||||
bool Debugger::observesNewScript() const { return getHook(OnNewScript); }
|
||||
bool Debugger::observesNewScript() const {
|
||||
return enabled && getHook(OnNewScript);
|
||||
}
|
||||
|
||||
bool Debugger::observesNewGlobalObject() const {
|
||||
return getHook(OnNewGlobalObject);
|
||||
return enabled && getHook(OnNewGlobalObject);
|
||||
}
|
||||
|
||||
bool Debugger::observesGlobal(GlobalObject* global) const {
|
||||
|
@ -145,6 +145,10 @@ bool DebuggerMemory::setTrackingAllocationSites(JSContext* cx, unsigned argc,
|
||||
|
||||
dbg->trackingAllocationSites = enabling;
|
||||
|
||||
if (!dbg->enabled) {
|
||||
return undefined(args);
|
||||
}
|
||||
|
||||
if (enabling) {
|
||||
if (!dbg->addAllocationsTrackingForAllDebuggees(cx)) {
|
||||
dbg->trackingAllocationSites = false;
|
||||
@ -333,7 +337,7 @@ bool DebuggerMemory::setAllocationSamplingProbability(JSContext* cx,
|
||||
|
||||
// If this is a change any debuggees would observe, have all debuggee
|
||||
// realms recompute their sampling probabilities.
|
||||
if (dbg->trackingAllocationSites) {
|
||||
if (dbg->enabled && dbg->trackingAllocationSites) {
|
||||
for (auto r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
|
||||
r.front()->realm()->chooseAllocationSamplingProbability();
|
||||
}
|
||||
|
@ -40,7 +40,8 @@ EnterDebuggeeNoExecute* EnterDebuggeeNoExecute::findInStack(JSContext* cx) {
|
||||
for (EnterDebuggeeNoExecute* it = cx->noExecuteDebuggerTop; it;
|
||||
it = it->prev_) {
|
||||
Debugger& dbg = it->debugger();
|
||||
if (!it->unlocked_ && dbg.observesGlobal(debuggee->maybeGlobal())) {
|
||||
if (!it->unlocked_ && dbg.isEnabled() &&
|
||||
dbg.observesGlobal(debuggee->maybeGlobal())) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ namespace js {
|
||||
|
||||
class LeaveDebuggeeNoExecute;
|
||||
|
||||
// Prevents all the debuggeee compartments of a given Debugger from executing
|
||||
// scripts. Attempts to run script will throw an
|
||||
// Given a Debugger instance dbg, if it is enabled, prevents all its debuggee
|
||||
// compartments from executing scripts. Attempts to run script will throw an
|
||||
// instance of Debugger.DebuggeeWouldRun from the topmost locked Debugger's
|
||||
// compartment.
|
||||
class MOZ_RAII EnterDebuggeeNoExecute {
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
js/src/jit-test/tests/binast/lazy/debug/dispatch-02.binjs
Normal file
BIN
js/src/jit-test/tests/binast/lazy/debug/dispatch-02.binjs
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
js/src/jit-test/tests/binast/nonlazy/debug/dispatch-02.binjs
Normal file
BIN
js/src/jit-test/tests/binast/nonlazy/debug/dispatch-02.binjs
Normal file
Binary file not shown.
@ -21,6 +21,14 @@ assertEq(asmLink(asmCompile(asmFunStr))(), undefined);
|
||||
g.dbg.allowUnobservedAsmJS = false;
|
||||
assertAsmTypeFail(asmFunStr);
|
||||
|
||||
// Disabling the debugger should uninhibit.
|
||||
g.dbg.enabled = false;
|
||||
assertEq(asmLink(asmCompile(asmFunStr))(), undefined);
|
||||
|
||||
// Enabling it should inhibit again.
|
||||
g.dbg.enabled = true;
|
||||
assertAsmTypeFail(asmFunStr);
|
||||
|
||||
// Removing the global should lift the inhibition.
|
||||
g.dbg.removeDebuggee(this);
|
||||
assertEq(asmLink(asmCompile(asmFunStr))(), undefined);
|
||||
|
18
js/src/jit-test/tests/debug/Debugger-enabled-01.js
Normal file
18
js/src/jit-test/tests/debug/Debugger-enabled-01.js
Normal file
@ -0,0 +1,18 @@
|
||||
var desc = Object.getOwnPropertyDescriptor(Debugger.prototype, "enabled");
|
||||
assertEq(typeof desc.get, 'function');
|
||||
assertEq(typeof desc.set, 'function');
|
||||
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var hits;
|
||||
var dbg = new Debugger(g);
|
||||
assertEq(dbg.enabled, true);
|
||||
dbg.onDebuggerStatement = function () { hits++; };
|
||||
|
||||
var vals = [true, false, null, undefined, NaN, "blah", {}];
|
||||
for (var i = 0; i < vals.length; i++) {
|
||||
dbg.enabled = vals[i];
|
||||
assertEq(dbg.enabled, !!vals[i]);
|
||||
hits = 0;
|
||||
g.eval("debugger;");
|
||||
assertEq(hits, vals[i] ? 1 : 0);
|
||||
}
|
17
js/src/jit-test/tests/debug/Debugger-enabled-02.js
Normal file
17
js/src/jit-test/tests/debug/Debugger-enabled-02.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Tests that hooks work if set while the Debugger is disabled.
|
||||
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var dbg = new Debugger(g);
|
||||
var log = "";
|
||||
|
||||
g.eval("" + function f() { return 42; });
|
||||
|
||||
dbg.enabled = false;
|
||||
dbg.onEnterFrame = function (frame) {
|
||||
log += "1";
|
||||
};
|
||||
dbg.enabled = true;
|
||||
|
||||
g.f();
|
||||
|
||||
assertEq(log, "1");
|
@ -12,3 +12,13 @@ dbg.onNewGlobalObject = function (global) {
|
||||
log = '';
|
||||
newGlobal();
|
||||
assertEq(log, 'n');
|
||||
|
||||
log = '';
|
||||
dbg.enabled = false;
|
||||
newGlobal();
|
||||
assertEq(log, '');
|
||||
|
||||
log = '';
|
||||
dbg.enabled = true;
|
||||
newGlobal();
|
||||
assertEq(log, 'n');
|
||||
|
@ -9,10 +9,12 @@ var hit;
|
||||
function handler(global) {
|
||||
hit++;
|
||||
log += hit;
|
||||
if (hit == 2)
|
||||
dbg1.enabled = dbg2.enabled = dbg3.enabled = false;
|
||||
};
|
||||
|
||||
log = '';
|
||||
hit = 0;
|
||||
dbg1.onNewGlobalObject = dbg2.onNewGlobalObject = dbg3.onNewGlobalObject = handler;
|
||||
newGlobal();
|
||||
assertEq(log, '123');
|
||||
assertEq(log, '12');
|
||||
|
@ -10,4 +10,8 @@ let promisesFound = [];
|
||||
dbg.onNewPromise = p => { promisesFound.push(p); };
|
||||
|
||||
let p1 = new g.Promise(function (){});
|
||||
dbg.enabled = false;
|
||||
let p2 = new g.Promise(function (){});
|
||||
|
||||
assertEq(promisesFound.indexOf(gw.makeDebuggeeValue(p1)) != -1, true);
|
||||
assertEq(promisesFound.indexOf(gw.makeDebuggeeValue(p2)) == -1, true);
|
||||
|
@ -16,3 +16,10 @@ g.settlePromiseNow(p);
|
||||
|
||||
assertEq(log, "s");
|
||||
assertEq(pw, gw.makeDebuggeeValue(p));
|
||||
|
||||
log = "";
|
||||
dbg.enabled = false;
|
||||
p = new g.Promise(function (){});
|
||||
g.settlePromiseNow(p);
|
||||
|
||||
assertEq(log, "");
|
||||
|
44
js/src/jit-test/tests/debug/Frame-onPop-disabled.js
Normal file
44
js/src/jit-test/tests/debug/Frame-onPop-disabled.js
Normal file
@ -0,0 +1,44 @@
|
||||
// An onPop handler in a disabled Debugger's frame shouldn't fire.
|
||||
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var dbg = new Debugger(g);
|
||||
g.eval('function f() { debugger; }');
|
||||
var log;
|
||||
dbg.onEnterFrame = function handleEnterFrame(f) {
|
||||
log += '(';
|
||||
assertEq(f.callee.name, 'f');
|
||||
f.onPop = function handlePop(c) {
|
||||
log += ')';
|
||||
assertEq(dbg.enabled, true);
|
||||
};
|
||||
};
|
||||
|
||||
var enable;
|
||||
dbg.onDebuggerStatement = function handleDebugger(f) {
|
||||
dbg.enabled = enable;
|
||||
}
|
||||
|
||||
|
||||
// This should fire the onEnterFrame and onPop handlers.
|
||||
log = 'a';
|
||||
enable = true;
|
||||
g.f();
|
||||
|
||||
// This should fire the onEnterFrame handler, but not the onPop.
|
||||
log += 'b';
|
||||
enable = false;
|
||||
g.f();
|
||||
|
||||
// This should fire neither.
|
||||
log += 'c';
|
||||
dbg.enabled = false;
|
||||
enable = false;
|
||||
g.f();
|
||||
|
||||
// This should fire both again.
|
||||
log += 'd';
|
||||
dbg.enabled = true;
|
||||
enable = true;
|
||||
g.f();
|
||||
|
||||
assertEq(log, 'a()b(cd()');
|
36
js/src/jit-test/tests/debug/Frame-onPop-multiple-03.js
Normal file
36
js/src/jit-test/tests/debug/Frame-onPop-multiple-03.js
Normal file
@ -0,0 +1,36 @@
|
||||
// One Debugger's onPop handler can disable another Debugger.
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var dbg1 = new Debugger(g);
|
||||
var dbg2 = new Debugger(g);
|
||||
|
||||
var log;
|
||||
var frames = [];
|
||||
var firstPop = true;
|
||||
|
||||
function handleEnter(frame) {
|
||||
log += '(';
|
||||
frames.push(frame);
|
||||
frame.debugger = this;
|
||||
frame.onPop = function handlePop(completion) {
|
||||
log += ')';
|
||||
assertEq(completion.return, 42);
|
||||
if (firstPop) {
|
||||
// We can't say which frame's onPop handler will get called first.
|
||||
if (this == frames[0])
|
||||
frames[1].debugger.enabled = false;
|
||||
else
|
||||
frames[0].debugger.enabled = false;
|
||||
} else {
|
||||
assertEq("second pop handler was called",
|
||||
"second pop handler should not be called");
|
||||
}
|
||||
firstPop = false;
|
||||
};
|
||||
};
|
||||
|
||||
dbg1.onEnterFrame = handleEnter;
|
||||
dbg2.onEnterFrame = handleEnter;
|
||||
|
||||
log = '';
|
||||
assertEq(g.eval('40 + 2'), 42);
|
||||
assertEq(log, '(()');
|
17
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-12.js
Normal file
17
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-12.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that disabling the debugger disables allocation tracking.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
const dbg = new Debugger();
|
||||
const root = newGlobal({newCompartment: true});
|
||||
dbg.addDebuggee(root);
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
dbg.enabled = false;
|
||||
|
||||
root.eval("this.alloc = {}");
|
||||
|
||||
// We shouldn't accumulate allocations in our log while the debugger is
|
||||
// disabled.
|
||||
let allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length, 0);
|
@ -74,3 +74,32 @@ test("Setting trackingAllocationSites to true should throw if the debugger " +
|
||||
assertEq(isTrackingAllocations(root1, d1r1), false);
|
||||
assertEq(isTrackingAllocations(root2, d1r2), false);
|
||||
});
|
||||
|
||||
test("A Debugger isn't tracking allocation sites when disabled.",
|
||||
() => {
|
||||
dbg1.memory.trackingAllocationSites = true;
|
||||
let d1r1 = dbg1.addDebuggee(root1);
|
||||
|
||||
assertEq(isTrackingAllocations(root1, d1r1), true);
|
||||
dbg1.enabled = false;
|
||||
assertEq(isTrackingAllocations(root1, d1r1), false);
|
||||
});
|
||||
|
||||
test("Re-enabling throws an error if we can't reinstall allocations tracking " +
|
||||
"for all debuggees.",
|
||||
() => {
|
||||
dbg1.enabled = false
|
||||
dbg1.memory.trackingAllocationSites = true;
|
||||
let d1r1 = dbg1.addDebuggee(root1);
|
||||
let d1r2 = dbg1.addDebuggee(root2);
|
||||
|
||||
// Can't install allocation hooks for root2 with this set.
|
||||
root2.enableShellAllocationMetadataBuilder();
|
||||
|
||||
assertThrowsInstanceOf(() => dbg1.enabled = true,
|
||||
Error);
|
||||
|
||||
assertEq(dbg1.enabled, false);
|
||||
assertEq(isTrackingAllocations(root1, d1r1), false);
|
||||
assertEq(isTrackingAllocations(root2, d1r2), false);
|
||||
});
|
||||
|
21
js/src/jit-test/tests/debug/dispatch-02.js
Normal file
21
js/src/jit-test/tests/debug/dispatch-02.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Disabling a Debugger object causes events to stop being delivered to it
|
||||
// immediately, even if we're in the middle of dispatching.
|
||||
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var log;
|
||||
|
||||
var arr = [];
|
||||
for (var i = 0; i < 4; i++) {
|
||||
arr[i] = new Debugger(g);
|
||||
arr[i].num = i;
|
||||
arr[i].onDebuggerStatement = function () {
|
||||
log += this.num;
|
||||
// Disable them all.
|
||||
for (var j = 0; j < arr.length; j++)
|
||||
arr[j].enabled = false;
|
||||
};
|
||||
}
|
||||
|
||||
log = '';
|
||||
g.eval("debugger; debugger;");
|
||||
assertEq(log, '0');
|
@ -22,6 +22,10 @@ var handlers = [() => { g.f(); },
|
||||
function testHookEnabled(hookName, trigger) {
|
||||
for (var h of handlers) {
|
||||
assertThrowsInstanceOf(h, Debugger.DebuggeeWouldRun);
|
||||
dbg.enabled = false;
|
||||
h();
|
||||
dbg.enabled = true;
|
||||
assertThrowsInstanceOf(h, Debugger.DebuggeeWouldRun);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ function test(mode, expected) {
|
||||
log += x;
|
||||
`);
|
||||
assertEq(g.log, expected);
|
||||
dbg.removeDebuggee(g);
|
||||
dbg.enabled = false;
|
||||
}
|
||||
|
||||
// We fire onEnterFrame for the initial activation when a generator is first
|
||||
|
@ -65,7 +65,7 @@ function run_test() {
|
||||
ok(debuggeree.fired >= 1);
|
||||
ok(fired >= 1);
|
||||
|
||||
debuggeree.dbg.removeAllDebuggees();
|
||||
debuggeree.dbg.enabled = dbg.enabled = false;
|
||||
do_test_finished();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user