[Webkit-unassigned] [Bug 160337] New: Crash in JavaScriptCore GC when using JSC on dispatch queues
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Fri Jul 29 04:46:23 PDT 2016
https://bugs.webkit.org/show_bug.cgi?id=160337
Bug ID: 160337
Summary: Crash in JavaScriptCore GC when using JSC on dispatch
queues
Classification: Unclassified
Product: WebKit
Version: Other
Hardware: iOS
OS: iOS 9.3
Status: NEW
Severity: Normal
Priority: P2
Component: JavaScriptCore
Assignee: webkit-unassigned at lists.webkit.org
Reporter: nham at fb.com
We recently enabled the use of JSC APIs in our app from dispatch queues. This lead to a number of crashes in the JSC GC timer so we had to remove this feature from our app. This implies that it's not safe to use JSC on a dispatch queue.
The crashing stack looks like this on iOS 8 (EXC_BAD_ADDRESS at 0x0):
Thread #15 Crashed:
0 JavaScriptCore JSC::ConservativeRoots::add(void*, void*, JSC::JITStubRoutineSet&, JSC::CodeBlockSet&) + 88
1 JavaScriptCore JSC::MachineThreads::gatherFromOtherThread(JSC::ConservativeRoots&, JSC::MachineThreads::Thread*, JSC::JITStubRoutineSet&, JSC::CodeBlockSet&) + 132
2 JavaScriptCore JSC::MachineThreads::gatherFromOtherThread(JSC::ConservativeRoots&, JSC::MachineThreads::Thread*, JSC::JITStubRoutineSet&, JSC::CodeBlockSet&) + 132
3 JavaScriptCore JSC::MachineThreads::gatherConservativeRoots(JSC::ConservativeRoots&, JSC::JITStubRoutineSet&, JSC::CodeBlockSet&, void*, int (&) [48]) + 384
4 JavaScriptCore JSC::Heap::markRoots(double) + 432
5 JavaScriptCore JSC::Heap::collect(JSC::HeapOperation) + 376
6 JavaScriptCore JSC::GCActivityCallback::doWork() + 144
7 JavaScriptCore JSC::HeapTimer::timerDidFire(__CFRunLoopTimer*, void*) + 196
8 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 24
9 CoreFoundation __CFRunLoopDoTimer + 884
10 CoreFoundation __CFRunLoopRun + 1368
11 CoreFoundation CFRunLoopRunSpecific + 392
12 Facebook +[RCTJSCExecutor runRunLoopThread] (RCTJSCExecutor.mm:280)
13 Foundation __NSThread__main__ + 1068
14 libsystem_pthread.dylib _pthread_body + 160
15 libsystem_pthread.dylib _pthread_start + 156
16 libsystem_pthread.dylib thread_start + 0
Basically, this is the marker segfaulting on trying to dereference a stack pointer of 0x0 for the target thread. (For this crash, we actually have a dump of the entire state of the stack in this crash, and were able to walk up the stack and find the Thread::Registers instance right on the stack clearly showing a SP of 0x0.)
The crashing stack looks like this on iOS 9 (EXC_BAD_ACCESS at 0xbbadbeef):
Thread #11 Crashed:
0 JavaScriptCore bmalloc::Heap::allocateXLarge(std::__1::lock_guard<bmalloc::StaticMutex>&, unsigned long) + 36
1 JavaScriptCore bmalloc::Heap::allocateXLarge(std::__1::lock_guard<bmalloc::StaticMutex>&, unsigned long) + 20
2 JavaScriptCore bmalloc::Allocator::allocateXLarge(unsigned long) + 92
3 JavaScriptCore JSC::MachineThreads::gatherConservativeRoots(JSC::ConservativeRoots&, JSC::JITStubRoutineSet&, JSC::CodeBlockSet&, void*, void*, int (&) [48]) + 176
4 JavaScriptCore JSC::Heap::markRoots(double, void*, void*, int (&) [48]) + 384
5 JavaScriptCore JSC::Heap::collectImpl(JSC::HeapOperation, void*, void*, int (&) [48]) + 612
6 JavaScriptCore JSC::Heap::collect(JSC::HeapOperation) + 92
7 JavaScriptCore JSC::GCActivityCallback::doWork() + 88
8 JavaScriptCore JSC::HeapTimer::timerDidFire(__CFRunLoopTimer*, void*) + 216
9 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 24
10 CoreFoundation __CFRunLoopDoTimer + 880
11 CoreFoundation __CFRunLoopRun + 1516
12 CoreFoundation CFRunLoopRunSpecific + 380
13 Facebook +[RCTJSCExecutor runRunLoopThread] (RCTJSCExecutor.mm:280)
14 Foundation __NSThread__start__ + 996
15 libsystem_pthread.dylib _pthread_body + 152
16 libsystem_pthread.dylib _pthread_start + 152
17 libsystem_pthread.dylib thread_start + 0
Basically, this is bmalloc crashing on purpose because vm_allocate can't allocate a large enough contiguous region to hold the target thread's stack, presumably because JSC thinks the stack is ginormous due to it having a SP of 0x0.
It looks like the basic issue here is that JSC uses thread_get_state to the the stack pointer of the target thread. Unfortunately, thread_get_state sometimes returns a SP of 0x0 for a thread. See <rdar://27607384> and https://openradar.appspot.com/27607384 for more details. Basically, when the target thread is a dispatch queue thread that's just about to run with this call stack:
Thread #32:
0 libsystem_pthread.dylib start_wqthread + 0
then thread_get_state may return 0x0 for the SP, causing the crashes in JSC GC outlined above.
It's unclear to me whether this is actually a kernel bug or a JSC bug, but it seems like it might be a good idea for JSC to be defensive against a SP of 0x0 and have it abort marking if a thread is in this state. Additionally, it seems like MachineStackMarker.cpp should do some sort of sanity check on the size of the stack and not try to allocate a ginormous buffer to hold a thread's stack. For instance, on iOS I believe the maximum size of a stack is 1 MB, so JSC should never be allocating more than that amount of space to hold a single thread's stack.
--
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20160729/8852f2bb/attachment.html>
More information about the webkit-unassigned
mailing list