commit 48897b0f83d4b2674eaf1fa0401174d36a8ad30b
parent 3e724a64beb59bacc4dbca0b7b377cd3c5a2e1a9
Author: Jan de Mooij <jdemooij@mozilla.com>
Date: Thu, 8 Jan 2026 08:12:46 +0000
Bug 2008675 - Call unsetIsDebuggee if needed when handling OOM in AutoRestoreRealmDebugMode. r=jonco
Differential Revision: https://phabricator.services.mozilla.com/D278102
Diffstat:
4 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
@@ -223,7 +223,7 @@ bool js::ValueToIdentifier(JSContext* cx, HandleValue v, MutableHandleId id) {
class js::AutoRestoreRealmDebugMode {
Realm* realm_;
- unsigned bits_;
+ uint32_t bits_;
public:
explicit AutoRestoreRealmDebugMode(Realm* realm)
@@ -233,7 +233,7 @@ class js::AutoRestoreRealmDebugMode {
~AutoRestoreRealmDebugMode() {
if (realm_) {
- realm_->debugModeBits_ = bits_;
+ realm_->restoreDebugModeBitsOnOOM(bits_);
}
}
diff --git a/js/src/jit-test/tests/debug/bug2008675.js b/js/src/jit-test/tests/debug/bug2008675.js
@@ -0,0 +1,10 @@
+function f() {
+ dbg.addDebuggee(g);
+ dbg.removeDebuggee(g);
+}
+var g = newGlobal({newCompartment: true});
+var dbg = new Debugger();
+dbg.onEnterFrame = f;
+oomTest(f);
+oomTest(f);
+oomTest(f);
diff --git a/js/src/vm/Realm.cpp b/js/src/vm/Realm.cpp
@@ -483,6 +483,22 @@ void Realm::unsetIsDebuggee() {
}
}
+void Realm::restoreDebugModeBitsOnOOM(uint32_t bits) {
+ // This is called from Debugger::addDebuggeeGlobal after calling
+ // Realm::setIsDebuggee. If the realm was not a debuggee realm before, we need
+ // to call unsetIsDebuggee to update counters on the JSRuntime.
+
+ MOZ_RELEASE_ASSERT(isDebuggee());
+
+ if (!(bits & IsDebuggee)) {
+ MOZ_ASSERT(bits == 0);
+ unsetIsDebuggee();
+ MOZ_ASSERT(debugModeBits_ == 0);
+ } else {
+ debugModeBits_ = bits;
+ }
+}
+
void Realm::updateDebuggerObservesCoverage() {
bool previousState = debuggerObservesCoverage();
updateDebuggerObservesFlag(DebuggerObservesCoverage);
diff --git a/js/src/vm/Realm.h b/js/src/vm/Realm.h
@@ -406,7 +406,7 @@ class JS::Realm : public JS::shadow::Realm {
DebuggerObservesWasm = 1 << 4,
DebuggerObservesNativeCall = 1 << 5,
};
- unsigned debugModeBits_ = 0;
+ uint32_t debugModeBits_ = 0;
friend class js::AutoRestoreRealmDebugMode;
bool isSystem_ = false;
@@ -478,6 +478,7 @@ class JS::Realm : public JS::shadow::Realm {
private:
void updateDebuggerObservesFlag(unsigned flag);
+ void restoreDebugModeBitsOnOOM(uint32_t bits);
Realm(const Realm&) = delete;
void operator=(const Realm&) = delete;