Assertion failure: bound(), at jit/shared/Assembler-shared.h:445 with Wasm stack switching
Categories
(Core :: JavaScript: WebAssembly, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox152 | --- | fixed |
People
(Reporter: jandem, Assigned: yury)
References
(Blocks 1 open bug)
Details
Attachments
(1 file)
|
48 bytes,
text/x-phabricator-request
|
Details |
Summary
An OOM during Ion code generation for the wasm resume instruction with
multiple handlers causes an assertion failure bound() in
CodeGenerator::visitWasmResume at Assembler-shared.h:445. The oomTest
harness triggers this reliably.
Root cause
In CodeGenerator::visitWasmResume (CodeGenerator.cpp:10580), the function
calls wasm::EmitResume(...) passing &resumeCodeOffset as an output
parameter (line 10621). If an OOM occurs inside EmitResume (e.g., during
MacroAssembler operations), the function doesn't actually emit code, and
resumeCodeOffset is left in its default unbound state.
However, immediately after EmitResume, line 10625 calls:
markSafepointAt(resumeCodeOffset.offset(), lir);
This calls resumeCodeOffset.offset() which asserts bound() — i.e., it
expects the CodeOffset to have been set by EmitResume. Under OOM, this
assertion fires, causing a crash (SEGV from MOZ_CrashSequence).
The function already has an OOM check for handlerLabels.reserve() at line
10611 (with a return), but there's no OOM check after EmitResume before
accessing its output parameter.
Possible fix
Add an OOM check after EmitResume:
wasm::EmitResume(masm, instance, cont, handlersParamsArea, ...
&resumeCodeOffset, &resumeFramePushed);
if (masm.oom()) {
return;
}
markSafepointAt(resumeCodeOffset.offset(), lir);
Expected vs. observed
- Expected: OOM is handled gracefully; compilation fails and returns an
OOM error to JS. - Observed:
Assertion failure: bound()at Assembler-shared.h:445,
followed by SEGV.
Shell output
[1520] Assertion failure: bound(), at /firefox/js/src/jit/shared/Assembler-shared.h:445
#0 MOZ_CrashSequence /firefox/obj-shell-dbgopt/dist/include/mozilla/Assertions.h:261
#1 js::jit::CodeOffset::offset() /firefox/js/src/jit/shared/Assembler-shared.h:445
#2 js::jit::CodeGenerator::visitWasmResume(LWasmResume*) CodeGenerator.cpp:10625
#3 js::jit::CodeGenerator::generateBlock(...) CodeGenerator.cpp:8681
...
| Reporter | ||
Comment 1•19 days ago
|
||
Test case (tested at git commit 410a52656dd13aa2360a3e96788e41bf48e80c0f):
// --fuzzing-safe -P wasm_stack_switching --wasm-compiler=ion
const bin = wasmTextToBinary(`(module
(type $ft (func))
(type $ct (cont $ft))
(tag $tag1)
(tag $tag2)
(tag $tag3)
(func $f (type $ft))
(elem declare func $f)
(func (export "run")
(block (result (ref $ct))
(block (result (ref $ct))
(block (result (ref $ct))
ref.func $f
cont.new $ct
resume $ct (on $tag1 0) (on $tag2 1) (on $tag3 2)
unreachable
)
unreachable
)
unreachable
)
drop
)
)`);
oomTest(function() {
var m = new WebAssembly.Module(bin);
return new WebAssembly.Instance(m, {});
});
| Assignee | ||
Comment 2•17 days ago
|
||
Updated•17 days ago
|
Updated•17 days ago
|
Comment 4•16 days ago
|
||
| bugherder | ||
Description
•