Bug 126764

Summary: REGRESSION(C stack work): stack traces no longer work in CrashTracer, lldb, and other tools
Product: WebKit Reporter: Michael Saboff <msaboff>
Component: JavaScriptCoreAssignee: Michael Saboff <msaboff>
Status: RESOLVED FIXED    
Severity: Normal Keywords: InRadar
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Attachments:
Description Flags
Patch ggaren: review+

Description Michael Saboff 2014-01-10 10:55:39 PST
From <rdar://problem/15713914>.

This is due to callToJavaScript not following the ABI calling convention.  First, JavaScript is executed on a separate stack with the frame register (rbp for X86) pointing at the JavaScript stack while the stack pointer register still points at the C stack.  Second, callToJavaScript doesn't follow the standard prologue expected by the unwind code.
Comment 1 Michael Saboff 2014-01-10 11:59:50 PST
Created attachment 220871 [details]
Patch

Test this with lldb.  Still need to verify it works correctly with other tools.
Comment 2 Geoffrey Garen 2014-01-10 12:01:44 PST
Comment on attachment 220871 [details]
Patch

r=me

This is a solid short term solution while we work on a broader solution for backtracking through LLInt opcodes.
Comment 3 Michael Saboff 2014-01-10 15:12:43 PST
This patch is a partial solution.  Here are the results from various tools after this change.

For lldb, backtrace is able to unwind through callToJavaScript, intermediate LLInt opcodes and JIT'ed code. Sample output below.

For Problem Reporter, the backtrace trace will work except it can't backtrace through JIT'ed code.  Sample below.

For the stack trace from ASSERT() via WTFReportBacktrace(), no change.  Stack traces stop at the first JIT'ed frame, LLInt opcode or callToJavaScript.

For Instruments, no change. Each sampled JIT'ed address or LLInt opcode is a root of a tree.

lldb output:
(lldb) bt
* thread #1: tid = 0xc2f08b, 0x000000010039a418 JavaScriptCore`JSC::genericUnwind(vm=0x0000000104820000, callFrame=0x0000000109691dc8, exceptionValue=JSValue at 0x00007fff5fbfa8b8) + 24 at JITExceptions.cpp:46, queue = 'com.apple.main-thread, stop reason = breakpoint 1.4
    frame #0: 0x000000010039a418 JavaScriptCore`JSC::genericUnwind(vm=0x0000000104820000, callFrame=0x0000000109691dc8, exceptionValue=JSValue at 0x00007fff5fbfa8b8) + 24 at JITExceptions.cpp:46
    frame #1: 0x00000001004e448a JavaScriptCore`llint_slow_path_handle_exception(exec=0x0000000109691dc8, pc=0x0000000103700900) + 170 at LLIntSlowPaths.cpp:1326
    frame #2: 0x00000001004eaa5f JavaScriptCore`llint_throw_from_slow_path_trampoline + 15
    frame #3: 0x00000001004e7815 JavaScriptCore`callToJavaScript + 213
    frame #4: 0x0000000100397bef JavaScriptCore`JSC::JITCode::execute(this=0x0000000103730db0, vm=0x0000000104820000, protoCallFrame=0x00007fff5fbfabd8, topOfStack=0x0000000109691e28) + 159 at JITCode.cpp:48
    frame #5: 0x000000010037c274 JavaScriptCore`JSC::Interpreter::execute(this=0x0000000105008cb0, program=0x00000001096ceb70, callFrame=0x00000001036df9b0, thisObj=0x00000001036ffb70) + 4564 at Interpreter.cpp:907
    frame #6: 0x0000000100113aff JavaScriptCore`JSC::evaluate(exec=0x00000001036df9b0, source=0x00007fff5fbfc0c0, thisValue=JSValue at 0x00007fff5fbfc020, returnedException=0x00007fff5fbfc090) + 479 at Completion.cpp:82
    frame #7: 0x00000001003e312a JavaScriptCore`JSEvaluateScript(ctx=0x0000000109691e50, script=0x000000010372bb40, thisObject=0x00000001036ffb70, sourceURL=0x0000000103730ee0, startingLineNumber=1, exception=0x00007fff5fbfc250) + 362 at JSBase.cpp:61
    frame #8: 0x0000000100002fe8 testapi`MyObject_deleteProperty(context=0x0000000109691e50, object=0x00000001036ffb70, propertyName=0x0000000103732760, exception=0x00007fff5fbfc250) + 168 at testapi.c:219
    frame #9: 0x00000001003e65d1 JavaScriptCore`JSC::JSCallbackObject<JSC::JSDestructibleObject>::deleteProperty(cell=0x00000001036ffb70, exec=0x0000000109691e50, propertyName=PropertyName at 0x00007fff5fbfc2a0) + 353 at JSCallbackObjectFunctions.h:355
    frame #10: 0x00000001004df0a2 JavaScriptCore`llint_slow_path_del_by_id(exec=0x0000000109691e50, pc=0x000000010372d8e8) + 258 at LLIntSlowPaths.cpp:664
    frame #11: 0x00000001004eb3c0 JavaScriptCore`llint_op_del_by_id + 15
    frame #12: 0x00000001004e7815 JavaScriptCore`callToJavaScript + 213
    frame #13: 0x0000000100397bef JavaScriptCore`JSC::JITCode::execute(this=0x0000000103731630, vm=0x0000000104820000, protoCallFrame=0x00007fff5fbfc530, topOfStack=0x0000000109691eb0) + 159 at JITCode.cpp:48
    frame #14: 0x00000001003791d8 JavaScriptCore`JSC::Interpreter::execute(this=0x0000000105008cb0, eval=0x00000001096cebf0, callFrame=0x0000000109691eb8, thisValue=JSValue at 0x00007fff5fbfc6a8, scope=0x000000010a06fd80) + 2264 at Interpreter.cpp:1197
    frame #15: 0x00000001003788d1 JavaScriptCore`JSC::eval(callFrame=0x0000000109691eb8) + 1025 at Interpreter.cpp:152
    frame #16: 0x00000001003a6203 JavaScriptCore`operationCallEval(execCallee=0x0000000109691eb8) + 387 at JITOperations.cpp:630
    frame #17: 0x000034359d6027ee
    frame #18: 0x000034359d6027ee
    frame #19: 0x00000001004ebfd8 JavaScriptCore`llint_op_call + 207
    frame #20: 0x00000001004e7815 JavaScriptCore`callToJavaScript + 213
    frame #21: 0x0000000100397bef JavaScriptCore`JSC::JITCode::execute(this=0x0000000103726e40, vm=0x0000000104820000, protoCallFrame=0x00007fff5fbfdba8, topOfStack=0x0000000109691ff8) + 159 at JITCode.cpp:48
    frame #22: 0x000000010037c274 JavaScriptCore`JSC::Interpreter::execute(this=0x0000000105008cb0, program=0x00000001096cf570, callFrame=0x00000001036df9b0, thisObj=0x00000001036df970) + 4564 at Interpreter.cpp:907
    frame #23: 0x0000000100113aff JavaScriptCore`JSC::evaluate(exec=0x00000001036df9b0, source=0x00007fff5fbff050, thisValue=JSValue at 0x00007fff5fbfeff0, returnedException=0x00007fff5fbff078) + 479 at Completion.cpp:82
    frame #24: 0x0000000100462219 JavaScriptCore`JSScriptEvaluate(context=0x00000001036df9b0, script=0x00000001037025b0, thisValueRef=0x0000000000000000, exception=0x00007fff5fbff7d8) + 281 at JSScriptRef.cpp:141
    frame #25: 0x000000010000829f testapi`main(argc=2, argv=0x00007fff5fbffab0) + 18383 at testapi.c:1820
    frame #26: 0x00007fff9231b5fd libdyld.dylib`start + 1

Problem Reporter output (with triggering RELEASE_ASSERT() added):
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.apple.JavaScriptCore            0x000000010b2a7b7e WTFCrash + 62 (Assertions.cpp:333)
1   com.apple.JavaScriptCore            0x000000010af3d490 slow_path_add + 976 (CommonSlowPaths.cpp:364)
2   com.apple.JavaScriptCore            0x000000010b17bd4c llint_op_add + 252
3   com.apple.JavaScriptCore            0x000000010b17ed2b llint_op_call + 192
4   com.apple.JavaScriptCore            0x000000010b17af6d callToJavaScript + 194
5   com.apple.JavaScriptCore            0x000000010b091490 JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*, JSC::Register*) + 48 (VM.h:368)
6   com.apple.JavaScriptCore            0x000000010b06c928 JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 4392 (Interpreter.cpp:907)
7   com.apple.JavaScriptCore            0x000000010af3fd63 JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*) + 467 (Completion.cpp:82)
8   com.apple.WebCore                   0x000000010c08b671 WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&) + 305 (JSMainThreadExecState.h:62)
9   com.apple.WebCore                   0x000000010c08b809 WebCore::ScriptController::evaluate(WebCore::ScriptSourceCode const&) + 41 (ScriptController.cpp:163)
10  com.apple.WebCore                   0x000000010c092bef WebCore::ScriptElement::executeScript(WebCore::ScriptSourceCode const&) + 447 (ScriptElement.cpp:310)
11  com.apple.WebCore                   0x000000010c092cbf WebCore::ScriptElement::execute(WebCore::CachedScript*) + 95 (RefPtr.h:55)
12  com.apple.WebCore                   0x000000010c09730f WebCore::ScriptRunner::timerFired(WebCore::Timer<WebCore::ScriptRunner>*) + 511 (ScriptRunner.cpp:120)
13  com.apple.WebCore                   0x000000010c222c0f WebCore::ThreadTimers::sharedTimerFiredInternal() + 175 (ThreadTimers.cpp:135)
14  com.apple.WebCore                   0x000000010c0d5cfa WebCore::timerFired(__CFRunLoopTimer*, void*) + 58 (SharedTimerMac.mm:134)
15  com.apple.CoreFoundation            0x00007fff8fe987a4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
16  com.apple.CoreFoundation            0x00007fff8fe982df __CFRunLoopDoTimer + 1151
17  com.apple.CoreFoundation            0x00007fff8ff0996a __CFRunLoopDoTimers + 298
18  com.apple.CoreFoundation            0x00007fff8fe53b55 __CFRunLoopRun + 1525
19  com.apple.CoreFoundation            0x00007fff8fe53325 CFRunLoopRunSpecific + 309
20  com.apple.HIToolbox                 0x00007fff8addeb1d RunCurrentEventLoopInMode + 226
21  com.apple.HIToolbox                 0x00007fff8adde8c5 ReceiveNextEventCommon + 479
22  com.apple.HIToolbox                 0x00007fff8adde6ca _BlockUntilNextEventMatchingListInModeWithFilter + 65
23  com.apple.AppKit                    0x00007fff915bb5fe _DPSNextEvent + 1434
24  com.apple.AppKit                    0x00007fff915bac4b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
25  com.apple.AppKit                    0x00007fff915aebbc -[NSApplication run] + 553
26  com.apple.AppKit                    0x00007fff91599a53 NSApplicationMain + 940
27  com.apple.XPCService                0x00007fff895f9c0f _xpc_main + 385
28  libxpc.dylib                        0x00007fff8940eb82 xpc_main + 399
29  com.apple.WebKit.WebContent.Development     0x0000000104a046a0 main + 16 (XPCServiceMain.Development.mm:91)
30  libdyld.dylib                       0x00007fff93a6e5fd start + 1
Comment 4 Michael Saboff 2014-01-10 15:43:17 PST
Committed r161686: <http://trac.webkit.org/changeset/161686>