Last Comment Bug 753283 - Assertion failure: allocated(), at ../../gc/Heap.h:497 or Crash [@ js::gc::Arena::isAligned]
: Assertion failure: allocated(), at ../../gc/Heap.h:497 or Crash [@ js::gc::Ar...
: assertion, crash, testcase
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Trunk
: x86 Linux
: -- critical (vote)
: mozilla16
Assigned To: Bill McCloskey (:billm)
: 764416 (view as bug list)
Depends on:
Blocks: langfuzz 782782
  Show dependency treegraph
Reported: 2012-05-09 05:18 PDT by Christian Holler (:decoder)
Modified: 2013-01-14 08:44 PST (History)
8 users (show)
choller: in‑testsuite+
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

patch (5.64 KB, patch)
2012-05-11 21:41 PDT, Bill McCloskey (:billm)
bhackett1024: review+
Details | Diff | Review

Description Christian Holler (:decoder) 2012-05-09 05:18:52 PDT
The following test asserts/crashes on mozilla-central revision 75d817e6bf4d (options -m -n -a):

var summary = '';
function printStatus (msg) {
  var lines = msg.split ("\n");
function f() {\
    var ss = [\
        new f(Int8Array, propertyIsEnumerable, '[let (x = 3, y = 4) x].map(0)')\
try {\
} catch (e) {}\
  printStatus (summary);\
function g(n, h) {\
    var a = f;\
    if (n <= 0) \
    return f; \
    var t = g(n - 1, h);\
    var r = function(x) {    };\
g(80, f);\

Stepping through the assertion triggers some more and then crashes with SIGFPE (division by 0):

Program received signal SIGFPE, Arithmetic exception.
0x080fca5f in js::gc::Arena::isAligned (thing=4149285072, thingSize=0) at ../gc/Heap.h:574
574             return tailOffset % thingSize == 0;
(gdb) bt
#0  0x080fca5f in js::gc::Arena::isAligned (thing=4149285072, thingSize=0) at ../gc/Heap.h:574
#1  0x083127a9 in js::gc::Cell::isAligned (this=0xf75110d0) at ../gc/Heap.h:976
#2  0x0831a362 in js::gc::CheckMarkedThing<JSObject> (trc=0x8620b50, thing=0xf75110d0) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:89
#3  0x08318abb in js::gc::MarkInternal<JSObject> (trc=0x8620b50, thingp=0xffffb61c) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:103
#4  0x08313972 in js::gc::MarkKind (trc=0x8620b50, thingp=0xffffb61c, kind=JSTRACE_OBJECT) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:233
#5  0x08313e60 in js::gc::MarkValueInternal (trc=0x8620b50, v=0xf7704640) at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:329
#6  0x08313f80 in js::gc::MarkValueRoot (trc=0x8620b50, v=0xf7704640, name=0x8479356 "vm_stack") at /srv/repos/mozilla-central/js/src/gc/Marking.cpp:349
#7  0x0829f399 in js::StackSpace::markFrameSlots (this=0x85f9b50, trc=0x8620b50, fp=0xf77045f0, slotsEnd=0xf7704650, pc=0x8620c9f "W") at /srv/repos/mozilla-central/js/src/vm/Stack.cpp:492
#8  0x0829f517 in js::StackSpace::mark (this=0x85f9b50, trc=0x8620b50) at /srv/repos/mozilla-central/js/src/vm/Stack.cpp:527
#9  0x08102f23 in js::MarkRuntime (trc=0x8620b50, useSavedRoots=false) at /srv/repos/mozilla-central/js/src/jsgc.cpp:2322
#10 0x081077a2 in js::gc::StartVerifyBarriers (rt=0x85f9b28) at /srv/repos/mozilla-central/js/src/jsgc.cpp:4254
#11 0x0810805d in js::gc::MaybeVerifyBarriers (cx=0x861dd50, always=false) at /srv/repos/mozilla-central/js/src/jsgc.cpp:4433
#12 0x0815653f in js::Interpret (cx=0x861dd50, entryFrame=0xf7702088, interpMode=js::JSINTERP_NORMAL) at /srv/repos/mozilla-central/js/src/jsinterp.cpp:3283

The opt build is all happy with the test, but I'm marking s-s anyway until this is confirmed to be debug-only/harmless, since it seems that there is something wrong with alignment. Before reduction, the test had this assertion which later didn't show up anymore:

Assertion failure: thing->isAligned(), at gc/Marking.cpp:89
Comment 1 Bill McCloskey (:billm) 2012-05-11 21:41:35 PDT
Created attachment 623390 [details] [diff] [review]

This is another exact stack scanning bug, although I think it's a debug-only problem.

We execute bytecode that looks like this:
00046:  lambda (function (x) {})
00051:  setlocal 2

Currently, the write barrier verifier is called at the beginning of every op in the interpreter, before any code runs for it. However, at that time the JSOP_SETLOCAL code hasn't had a chance to write to slot #2 yet. So we crash when we scan the stack and see bad data in slot #2, which it thinks is live.

This patch moves the write barrier verifier call so that it happens at the end of the op, rather than at the beginning. I'm a little worried that this will just expose other cases where we behave badly. So I added some stack poisoning code that should make it easier for the fuzzers to catch these bugs. I'm pretty sure that the poisoning shouldn't affect register allocation, so hopefully the semantics of the code won't change (aside from the stack slots getting poisoned).
Comment 2 Brian Hackett (:bhackett) 2012-05-14 06:36:51 PDT
Comment on attachment 623390 [details] [diff] [review]

Review of attachment 623390 [details] [diff] [review]:

::: js/src/methodjit/Compiler.cpp
@@ +1224,5 @@
>          if (lifetime)
>              masm.storeValue(UndefinedValue(), local);
> +#ifdef DEBUG
> +        else
> +            masm.storeValue(ObjectValue(*reinterpret_cast<JSObject *>(0x42)), local);

How about adding an ObjectValueCrashOnTouch()?

@@ +1243,5 @@
> +#ifdef DEBUG
> +    uint32_t depth = ssa.getFrame(a->inlineIndex).depth;
> +    for (uint32_t i = script->nfixed; i < script->nslots; i++) {
> +        Address local(JSFrameReg, sizeof(StackFrame) + (depth + i) * sizeof(Value));
> +        masm.storeValue(ObjectValue(*reinterpret_cast<JSObject *>(0x42)), local);

Comment 4 Bill McCloskey (:billm) 2012-05-16 14:58:17 PDT

This had tons of orange.
Comment 6 Bill McCloskey (:billm) 2012-05-25 13:52:31 PDT
I had to back this out again because it was turning windows debug builds purple during "make check". FML.
Comment 8 Ed Morley [:emorley] 2012-06-13 06:00:14 PDT
Comment 9 Bill McCloskey (:billm) 2012-06-13 18:00:58 PDT
*** Bug 764416 has been marked as a duplicate of this bug. ***
Comment 10 Christian Holler (:decoder) 2013-01-14 08:44:22 PST
A testcase for this bug was automatically identified at js/src/jit-test/tests/basic/bug753283.js.

Note You need to log in before you can comment on or make changes to this bug.