Closed Bug 762547 Opened 12 years ago Closed 12 years ago

IonMonkey: Assertion failure: addr % Cell::CellSize == 0, at ../../gc/Heap.h:832 with memory corruption

Categories

(Core :: JavaScript Engine, defect)

Other Branch
x86_64
Linux
defect
Not set
major

Tracking

()

RESOLVED FIXED
Tracking Status
firefox-esr10 --- unaffected

People

(Reporter: decoder, Unassigned)

References

Details

(Keywords: assertion, crash, testcase, Whiteboard: [jsbugmon:update][fuzzblocker])

Attachments

(2 files)

Attached file Testcase for shell
The attached testcase asserts on ionmonkey revision 8acbac4d6cfd (run with --ion -n -m --ion-eager).
This is some form of memory corruption that seems to cause multiple signatures right now in the fuzzer. Even this test kept switching between segfault and assertion without any test changes. I need a fix for this to reliably triage the other bugs found.
Keywords: crash
Whiteboard: [jsbugmon:update] → [jsbugmon:update][fuzzblocker]
decoder pointed out that it looked like it might be a double-free or invalid free leading to memory corruption based on valgrind.  I'm just attaching the relevant valgrind output here:

==43704== Invalid free() / delete / delete[] / realloc()
==43704==    at 0x506E: free (vg_replace_malloc.c:430)
==43704==    by 0x10000CE24: js_free (in /tmp/js)
==43704==    by 0x100015384: js::Foreground::free_(void*) (in /tmp/js)
==43704==    by 0x100027FC8: JSRuntime::free_(void*) (in /tmp/js)
==43704==    by 0x10007B757: js::FreeOp::free_(void*) (in /tmp/js)
==43704==    by 0x10058254C: js::ion::IonScript::Destroy(js::FreeOp*, js::ion::IonScript*) (in /tmp/js)
==43704==    by 0x100584361: js::ion::FinishInvalidation(js::FreeOp*, JSScript*) (in /tmp/js)
==43704==    by 0x1000CCF20: JSCompartment::discardJitCode(js::FreeOp*) (in /tmp/js)
==43704==    by 0x1000CD113: JSCompartment::sweep(js::FreeOp*, bool) (in /tmp/js)
==43704==    by 0x100119789: SweepPhase(JSRuntime*, js::JSGCInvocationKind, bool*) (in /tmp/js)
==43704==    by 0x100118A15: GCCycle(JSRuntime*, bool, long long, js::JSGCInvocationKind) (in /tmp/js)
==43704==    by 0x100113C9B: Collect(JSRuntime*, bool, long long, js::JSGCInvocationKind, js::gcreason::Reason) (in /tmp/js)
==43704==  Address 0x1013519f0 is 0 bytes inside a block of size 1,500 free'd
==43704==    at 0x506E: free (vg_replace_malloc.c:430)
==43704==    by 0x10000CE24: js_free (in /tmp/js)
==43704==    by 0x100015384: js::Foreground::free_(void*) (in /tmp/js)
==43704==    by 0x100027FC8: JSRuntime::free_(void*) (in /tmp/js)
==43704==    by 0x10007B757: js::FreeOp::free_(void*) (in /tmp/js)
==43704==    by 0x10058254C: js::ion::IonScript::Destroy(js::FreeOp*, js::ion::IonScript*) (in /tmp/js)
==43704==    by 0x1005878CC: js::ion::IonScript::decref(js::FreeOp*) (in /tmp/js)
==43704==    by 0x100545E41: js::ion::InvalidationBailout(js::ion::InvalidationBailoutStack*, unsigned long*) (in /tmp/js)
==43704==    by 0x2A28107: ???
==43704==    by 0x2D151BF: ???
==43704==    by 0x7FFF5FBF51F7: ???
==43704==    by 0x7FFF5FBF523F: ???
I think it's also helpful to look at the very first Valgrind error of this test (probably more helpful than the last error which actually causes the crash):

==23516== Invalid read of size 8
==23516==    at 0x7F3538: js::EncapsulatedPtr<js::ion::IonCode, unsigned long>::operator js::ion::IonCode*() const (Barrier.h:172)
==23516==    by 0x7EFE5B: js::ion::IonScript::trace(JSTracer*) (Ion.cpp:497)
==23516==    by 0x7F0861: js::ion::IonScript::Trace(JSTracer*, js::ion::IonScript*) (Ion.cpp:667)
==23516==    by 0x5C528F: JSScript::markChildren(JSTracer*) (jsscript.cpp:2134)
==23516==    by 0x70EF3C: js::gc::MarkChildren(JSTracer*, JSScript*) (Marking.cpp:808)
==23516==    by 0x7107FE: js::TraceChildren(JSTracer*, void*, JSGCTraceKind) (Marking.cpp:1335)
==23516==    by 0x440E95: JS_TraceChildren (jsapi.cpp:2544)
==23516==    by 0x4CE4DB: js::gc::StartVerifyBarriers(JSRuntime*) (jsgc.cpp:4438)
==23516==    by 0x4CEEA8: js::gc::MaybeVerifyBarriers(JSContext*, bool) (jsgc.cpp:4612)
==23516==    by 0x516A28: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:1554)
==23516==    by 0x511348: js::RunScript(JSContext*, JSScript*, js::StackFrame*) (jsinterp.cpp:268)
==23516==    by 0x512029: js::ExecuteKernel(JSContext*, JSScript*, JSObject&, JS::Value const&, js::ExecuteType, js::StackFrame*, JS::Value*) (jsinterp.cpp:474)
==23516==  Address 0x5e5f700 is 0 bytes inside a block of size 1,500 free'd
==23516==    at 0x4C2695D: free (vg_replace_malloc.c:366)
==23516==    by 0x403C14: js_free (Utility.h:169)
==23516==    by 0x403C4E: js::Foreground::free_(void*) (Utility.h:588)
==23516==    by 0x41AB3F: JSRuntime::free_(void*) (jscntxt.h:880)
==23516==    by 0x4279DA: js::FreeOp::free_(void*) (jscntxt.h:1070)
==23516==    by 0x7F0886: js::ion::IonScript::Destroy(js::FreeOp*, js::ion::IonScript*) (Ion.cpp:673)
==23516==    by 0x7E776E: js::ion::IonScript::decref(js::FreeOp*) (IonCode.h:407)
==23516==    by 0x7E8EBB: js::ion::InvalidationBailout(js::ion::InvalidationBailoutStack*, unsigned long*) (Bailouts.cpp:393)
==23516==    by 0x4032107: ???
==23516==    by 0x7FEFFD2EF: ???
==23516==    by 0x7FEFFD2A7: ???
==23516==    by 0x7FEFFD2CF: ???
Shorter testcase that works on 32 and 64 bit debug builds (asserts/crashes):


gcPreserveCode();
function testStrict() {
    var n = 10, a = [];
    for (var i = 0; i < 10; ++i) {
        a[0] = (gc());
        a[1] = (n !== 10);
        a[0x2 ] = (n === null);
        a[3] = (n == null);
    }
    return  ;  
}
assertEq(testStrict(), "true,false,false,false");


It shows similar Valgrind errors, but might be easier to debug due to smaller size.
Attached patch Patch.Splinter Review
Fixes both failing testcases.
Attachment #631074 - Flags: review?(dvander)
Attachment #631074 - Flags: review?(dvander) → review+
http://hg.mozilla.org/projects/ionmonkey/rev/d64bb62ab69c
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
http://hg.mozilla.org/projects/ionmonkey/rev/f664983ee584

Fix testcase to pass on opt builds by only calling gcPreserveCode() if it has a definition.
Group: core-security
You need to log in before you can comment on or make changes to this bug.