tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mjs/src/debugger/Debugger.cpp | 4++--
Ajs/src/jit-test/tests/debug/bug2008675.js | 10++++++++++
Mjs/src/vm/Realm.cpp | 16++++++++++++++++
Mjs/src/vm/Realm.h | 3++-
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;