Closed Bug 2033808 Opened 6 months ago Closed 6 months ago

Assertion failure: WeakMapBase::checkMarkingForZone(zone) @ gc/Sweeping.cpp:1260

Categories

(Core :: JavaScript: GC, defect, P2)

defect

Tracking

()

RESOLVED FIXED
152 Branch
Tracking Status
firefox152 --- fixed

People

(Reporter: x0e, Assigned: jonco)

References

(Blocks 3 open bugs)

Details

(Keywords: reporter-external)

Attachments

(1 external file)

Steps to reproduce:

Build information

engine version         : c34ebfaedf1a009f0bd13f1700e9b795a1b520c7
engine version date    : 2026-04-21T08:56:18
build date             : 2026-04-21T13:59:17.095440

Shell arguments

--fuzzing-safe <input.js>

Test input

new Uint32Array(4);
/[\p{Script_Extensions=Mongolian}&&\p{Number}]/uysm;
new Array(257);
[-1e-15,-1.6542446820991355e+308,0.8847244100836382,NaN,2.0,-5.0,-4.0,1000000000000.0,9.762882247425858,1e-15];
new Float64Array(13);
function f13() {
}
function f14(a15) {
    actual += a15 + ",";
}
var appendToActual = f14;
let hasFunction = {};
for (const v40 of ["gczeal","unsetgczeal","schedulegc","selectforgc","verifyprebarriers","verifypostbarriers","currentgc","det
    const present = v40 in this;
    if (!present) {
        function f45() {
        }
        this[v40] = f45;
    }
    hasFunction[v40] = present;
}
gcparam("parallelMarkingThresholdMB", 0);
function setup() {
    gczeal(0);
    let key = {};
    let value = {};
    const v61 = new WeakMap();
    var wm = v61;
    wm.set(key, value);
    const t29 = grayRoot();
    t29[0] = wm;
    addMarkObservers([key,wm,value]);
    wm = undefined;
    value = undefined;
    gczeal(11);
    gczeal(8);
    startgc(1);
    f13(gcstate(), "Mark");
    key = undefined;
    while (gcstate() !== "NotActive") {
        gcslice(1);
    }
    gczeal(0);
}
function test() {
    for (let i96 = 0; i96 < 10; i96++) {
        const v103 = newGlobal({ newCompartment: true });
        const v105 = Debugger(v103);
        v103.eval(`\nasync function f(){\n  await Promise.resolve();\n}\n`);
        function f108(a109) {
        }
        v105.onEnterFrame = f108;
        function f110() {
            v103.f();
        }
        f110();
        oomTest(setup);
    }
}
try {
    test();
} catch(e117) {
}
gc();

Backtrace

[546697] Assertion failure: WeakMapBase::checkMarkingForZone(zone), at .worktree-repro/js/src/gc/Sweeping.cpp:1261
#01: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x23e172f]
#02: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x242ca2c]
#03: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2417239]
#04: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x23ee127]
#05: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2326a0b]
#06: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x232a352]
#07: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x232bc9b]
#08: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x1f897fb]
#09: ??? (???:???)
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==546697==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x645664e0f747 bp 0x7ffdf8d71770 sp 0x
==546697==The signal is caused by a WRITE memory access.
==546697==Hint: address points to the zero page.
/opt/swift/usr/bin/llvm-symbolizer: error: '[anon:js-executable-memory]': No such file or directory
    #0 0x645664e0f747 in MOZ_CrashSequence(void*, long) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/dist
    #1 0x645664e0f747 in MaybeCheckWeakMapMarking(js::gc::GCRuntime*) targets/spidermonkey/artifacts/builds/reproducebuild-c34
    #2 0x645664e0f747 in js::gc::GCRuntime::endMarkingSweepGroup(JS::GCContext*, JS::SliceBudget&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/Sweeping.cpp:1377:3
    #3 0x645664e5aa2b in sweepaction::SweepActionSequence::run(js::gc::SweepAction::Args&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/Sweeping.cpp:2490:23
    #4 0x645664e45238 in sweepaction::SweepActionForEach<js::gc::SweepGroupsIter, JSRuntime*>::run(js::gc::SweepAction::Args&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/Sweeping.cpp:2525:19
    #5 0x645664e1c126 in js::gc::GCRuntime::sweepPhase(JS::SliceBudget&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/Sweeping.cpp:2727:55
    #6 0x645664d54a0a in js::gc::GCRuntime::incrementalSlice(JS::SliceBudget&, JS::GCReason, bool) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/GC.cpp:4383:11
    #7 0x645664d58351 in js::gc::GCRuntime::gcCycle(bool, JS::SliceBudget const&, JS::GCReason) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/GC.cpp:4947:3
    #8 0x645664d59c9a in js::gc::GCRuntime::collect(bool, JS::SliceBudget const&, JS::GCReason) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/GC.cpp:5137:9
    #9 0x6456649b77fa in GCSlice(JSContext*, unsigned int, JS::Value*) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/builtin/./../../../../../../.worktree-repro/js/src/builtin/TestingFunctions.cpp:3183:12
    #10 0x061428fbd722  ([anon:js-executable-memory]+0x6722)

==546697==Register values:
rax = 0x0000000000000000  rbx = 0x0000000000000001  rcx = 0x00000000000004ed  rdx = 0x0000000000000000
rdi = 0x00007f27f62b6780  rsi = 0x0000000000000000  rbp = 0x00007ffdf8d71770  rsp = 0x00007ffdf8d71700
 r8 = 0x0000000000000000   r9 = 0x0000000000000000  r10 = 0x0000000000000000  r11 = 0x00007f27f607b880
r12 = 0x00007f27f607b7d8  r13 = 0x00007f27f4e25040  r14 = 0x00007f27f3b0f000  r15 = 0x00007f27f4e2c948
UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/dist/include/mozilla/Assertions.h:261:3 in MOZ_CrashSequence(void*, long)
==546697==ABORTING
Group: firefox-core-security → core-security
Component: Untriaged → JavaScript Engine
Product: Firefox → Core
Group: core-security → javascript-core-security

Test case was cut in between:

Test input

new Uint32Array(4);
/[\p{Script_Extensions=Mongolian}&&\p{Number}]/uysm;
new Array(257);
[-1e-15,-1.6542446820991355e+308,0.8847244100836382,NaN,2.0,-5.0,-4.0,1000000000000.0,9.762882247425858,1e-15];
new Float64Array(13);
function f13() {
}
function f14(a15) {
    actual += a15 + ",";
}
var appendToActual = f14;
let hasFunction = {};
for (const v40 of ["gczeal","unsetgczeal","schedulegc","selectforgc","verifyprebarriers","verifypostbarriers","currentgc","deterministicgc","dumpGCArenaInfo","setMarkStackLimit","oomThreadTypes","oomAfterAllocations","oomAtAllocation","resetOOMFailure","oomTest","stackTest","interruptTest"]) {
    const present = v40 in this;
    if (!present) {
        function f45() {
        }
        this[v40] = f45;
    }
    hasFunction[v40] = present;
}
gcparam("parallelMarkingThresholdMB", 0);
function setup() {
    gczeal(0);
    let key = {};
    let value = {};
    const v61 = new WeakMap();
    var wm = v61;
    wm.set(key, value);
    const t29 = grayRoot();
    t29[0] = wm;
    addMarkObservers([key,wm,value]);
    wm = undefined;
    value = undefined;
    gczeal(11);
    gczeal(8);
    startgc(1);
    f13(gcstate(), "Mark");
    key = undefined;
    while (gcstate() !== "NotActive") {
        gcslice(1);
    }
    gczeal(0);
}
function test() {
    for (let i96 = 0; i96 < 10; i96++) {
        const v103 = newGlobal({ newCompartment: true });
        const v105 = Debugger(v103);
        v103.eval(`\nasync function f(){\n  await Promise.resolve();\n}\n`);
        function f108(a109) {
        }
        v105.onEnterFrame = f108;
        function f110() {
            v103.f();
        }
        f110();
        oomTest(setup);
    }
}
try {
    test();
} catch(e117) {
}
gc();
Severity: -- → S4
Priority: -- → P2
Component: JavaScript Engine → JavaScript: GC

Reduced test case:

function setup() {
    gczeal(11);
    gczeal(8);
    startgc(1);
    gcslice(1);
}
for (let i = 0; i < 2; i++) {
    const g = newGlobal({newCompartment: true});
    Debugger(g).onEnterFrame = function() {};
    g.eval(`(async()=>{await 0})()`);
}
oomTest(setup);

This is a bug in incremental marking validation which is not present in release builds. Not security sensitive.

Assignee: nobody → jcoppeard
Group: javascript-core-security

The testcase fails because we hit OOM in the non-incremental mark step but
carry on to compare this to the results of incremental marking and find they
don't match.

Non-incrementeal marking currently has some places where it crashes on OOM
(where it can't restore the original state). This patch extends this to crash
if it can't do the marking for other reasons. I moved this handling part out of
the main marking method for simplicity.

Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/d272e358fb0b https://hg.mozilla.org/integration/autoland/rev/97225cd4d973 Don't run incremental marking validation if we fail to run the non-incremental marking r=spidermonkey-reviewers,sfink
Status: NEW → RESOLVED
Closed: 6 months ago
Resolution: --- → FIXED
Target Milestone: --- → 152 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: