Bug 153819 - [JavaScriptCore] JavaScriptCore is crashed when PARRELLEL GC is enabled.
Summary: [JavaScriptCore] JavaScriptCore is crashed when PARRELLEL GC is enabled.
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Critical
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-02-02 21:20 PST by Peng Xinchao
Modified: 2016-02-02 23:18 PST (History)
32 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peng Xinchao 2016-02-02 21:20:51 PST
Hello, GC experts.

Recently I met a GC crash when PARRALLEL GC is enabled. Crash is like:

#0  0x00007ffff72a1671 in isJSString (this=0x7fffeaec0cd8) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSString.h:501
#1  visitChildren (this=0x7fffeaec0cd8) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:351
#2  JSC::SlotVisitor::drain (this=0x7fffeaec0cd8) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:405
#3  0x00007ffff72a19e4 in JSC::SlotVisitor::drainFromShared (this=0x7fffeaec0cd8, sharedDrainMode=JSC::SlotVisitor::MasterDrain) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:498
#4  0x00007ffff729dd38 in JSC::Heap::markRoots (this=0x7fffeaec0050, fullGC=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.cpp:555
#5  0x00007ffff729df8b in JSC::Heap::collect (this=0x7fffeaec0050, sweepToggle=JSC::Heap::DoNotSweep) at /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.cpp:717
#6  0x00007ffff72a410c in JSC::MarkedAllocator::allocateSlowCase (this=0x7fffeaec0158) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedAllocator.cpp:75
#7  0x00007ffff72e84ba in JSC::MarkedAllocator::allocate (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedAllocator.h:77
#8  JSC::MarkedSpace::allocateWithDestructor (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedSpace.h:191
#9  JSC::Heap::allocateWithDestructor (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.h:362
#10 allocateCell<JSC::JSFinalObject> (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSCell.h:340
#11 JSC::JSFinalObject::create (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSObject.h:439
#12 constructEmptyObject (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSObject.h:515
#13 constructEmptyObject (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h:431
#14 constructEmptyObject (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h:436
#15 operationNewObject (exec=<value optimized out>) at /home/oszi/WebKit/Source/JavaScriptCore/dfg/DFGOperations.cpp:305
#16 0x00007fffaaf8880d in ?? ()
#17 0x0000000000000000 in ?? ()


I checked the code of JSCore GC.

void SlotVisitor::drain()
{
    StackStats::probe();
    ASSERT(m_isInParallelMode);

#if ENABLE(PARALLEL_GC)
    if (Options::numberOfGCMarkers() > 1) {
        while (!m_stack.isEmpty()) {
            m_stack.refill();
            for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_stack.canRemoveLast() && countdown--;)
                visitChildren(*this, m_stack.removeLast());
            donateKnownParallel();
        }

        mergeOpaqueRootsIfNecessary();
        return;
    }
#endif

    while (!m_stack.isEmpty()) {
        m_stack.refill();
        while (m_stack.canRemoveLast())
            visitChildren(*this, m_stack.removeLast());
    }
}

Why is m_shared.m_markingLock not added before m_stack.refill() and m_stack.removeLast(), just like inside the function void SlotVisitor::donateKnownParallel() ?

It seems that m_stack is operated unsafely when PARRELLEL GC is enabled.

What do you think?
Comment 1 Alexey Proskuryakov 2016-02-02 22:35:43 PST
The code you pasted is from some old version of WebKit, however the behavior you question is still present. I don't know if it's indeed a concern.
Comment 2 Filip Pizlo 2016-02-02 22:56:17 PST
(In reply to comment #0)
> Hello, GC experts.
> 
> Recently I met a GC crash when PARRALLEL GC is enabled. Crash is like:
> 
> #0  0x00007ffff72a1671 in isJSString (this=0x7fffeaec0cd8) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSString.h:501
> #1  visitChildren (this=0x7fffeaec0cd8) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:351
> #2  JSC::SlotVisitor::drain (this=0x7fffeaec0cd8) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:405
> #3  0x00007ffff72a19e4 in JSC::SlotVisitor::drainFromShared
> (this=0x7fffeaec0cd8, sharedDrainMode=JSC::SlotVisitor::MasterDrain) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkStack.cpp:498
> #4  0x00007ffff729dd38 in JSC::Heap::markRoots (this=0x7fffeaec0050,
> fullGC=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.cpp:555
> #5  0x00007ffff729df8b in JSC::Heap::collect (this=0x7fffeaec0050,
> sweepToggle=JSC::Heap::DoNotSweep) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.cpp:717
> #6  0x00007ffff72a410c in JSC::MarkedAllocator::allocateSlowCase
> (this=0x7fffeaec0158) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedAllocator.cpp:75
> #7  0x00007ffff72e84ba in JSC::MarkedAllocator::allocate (exec=<value
> optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedAllocator.h:77
> #8  JSC::MarkedSpace::allocateWithDestructor (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/MarkedSpace.h:191
> #9  JSC::Heap::allocateWithDestructor (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/heap/Heap.h:362
> #10 allocateCell<JSC::JSFinalObject> (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSCell.h:340
> #11 JSC::JSFinalObject::create (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSObject.h:439
> #12 constructEmptyObject (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSObject.h:515
> #13 constructEmptyObject (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h:431
> #14 constructEmptyObject (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h:436
> #15 operationNewObject (exec=<value optimized out>) at
> /home/oszi/WebKit/Source/JavaScriptCore/dfg/DFGOperations.cpp:305
> #16 0x00007fffaaf8880d in ?? ()
> #17 0x0000000000000000 in ?? ()
> 
> 
> I checked the code of JSCore GC.
> 
> void SlotVisitor::drain()
> {
>     StackStats::probe();
>     ASSERT(m_isInParallelMode);
> 
> #if ENABLE(PARALLEL_GC)
>     if (Options::numberOfGCMarkers() > 1) {
>         while (!m_stack.isEmpty()) {
>             m_stack.refill();
>             for (unsigned countdown =
> Options::minimumNumberOfScansBetweenRebalance(); m_stack.canRemoveLast() &&
> countdown--;)
>                 visitChildren(*this, m_stack.removeLast());
>             donateKnownParallel();
>         }
> 
>         mergeOpaqueRootsIfNecessary();
>         return;
>     }
> #endif
> 
>     while (!m_stack.isEmpty()) {
>         m_stack.refill();
>         while (m_stack.canRemoveLast())
>             visitChildren(*this, m_stack.removeLast());
>     }
> }
> 
> Why is m_shared.m_markingLock not added before m_stack.refill() and
> m_stack.removeLast(), just like inside the function void
> SlotVisitor::donateKnownParallel() ?
> 
> It seems that m_stack is operated unsafely when PARRELLEL GC is enabled.
> 
> What do you think?

Not a bug.  m_stack is the thread-local stack.
Comment 3 Peng Xinchao 2016-02-02 23:18:57 PST
Thanks a lot for your quickly response.

m_stack is the thread-local stack, you are right. I made a mistake before.

But we met some similar crashes like:

#0  0x47dac0f0 in isJSString (v=...) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/JavaScriptCore/runtime/JSString.h:493
No locals.
#1  visitChildren (cell=0xb3ad5018, visitor=...) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/JavaScriptCore/heap/SlotVisitor.cpp:80
No locals.
#2  JSC::SlotVisitor::drain (this=this@entry=0xa54e8) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/JavaScriptCore/heap/SlotVisitor.cpp:136
        countdown = 32
#3  0x47dac3a0 in JSC::SlotVisitor::drainFromShared (this=0xa54e8, sharedDrainMode=JSC::SlotVisitor::SlaveDrain) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/JavaScriptCore/heap/SlotVisitor.cpp:225
No locals.
#4  0x47d9e2be in JSC::GCThread::gcThreadMain (this=0xa5550) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/JavaScriptCore/heap/GCThread.cpp:104
        enabler = {m_stack = @0xa54e8}
#5  0x47f4c2cc in WTF::wtfThreadEntryPoint (param=0xa5f98) at /usr/src/debug/webkit2-efl-tv-152340_0.10.193.0+tv/Source/WTF/wtf/ThreadingPthreads.cpp:195
        invocation = {m_ptr = 0xa5f98}
#6  0x42a56418 in start_thread (arg=0xb48ff070) at pthread_create.c:314
        pd = 0xb48ff070
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {-1081256549, 1235737603, -1265635216, 0, -1108857128, 338, -1238645568, 0, 0, -1265636436, 1, 0 <repeats 53 times>}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
        pagesize_m1 = <optimized out>
        sp = <optimized out>
        freesize = <optimized out>
        __PRETTY_FUNCTION__ = "start_thread"
#7  0x429597c0 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:89 from ./symbols/lib/libc.so.6
No locals.
Backtrace stopped: previous frame identical to this frame (corrupt stack?)


Our codes that have crashes are a little old.
Do you mean that the latest JavaScriptCore does not have this kind of crash? 

Is this crash PARALLEL GC's issue?
If PARALLEL GC is disabled, could the crash be avoided?

Because I have poor knowledge about GC, could you give me some suggestions?

Thanks very much!