哪里可以正确分析spindumps?
解决方法
>有一个崩溃报告,你得到一个堆栈跟踪
>使用spindumps,您可以在一段时间内一起获得多个堆栈跟踪.
有两种情况可能需要检查spindump:
第一种情况可以从spindump看到,通过多次调用相同的功能.在这种情况下使用的好东西是活动监视器 – 在这里抽取挂起的流程,您可以通过几种有用的方式查看它,隐藏不重要的框架等.
第二种情况可以由同时等待锁的不同线程查看.
这里有一个例子:
+ 2663 start (in MyApp) + 52 [0x100001bb4] + 2663 main (in MyApp) + 39 [0x100001be7] main.m:65 + 2663 NSApplicationMain (in AppKit) + 869 [0x7fff8ea27cb6] + 2663 -[NSApplication run] (in AppKit) + 517 [0x7fff8ea83283] + 2663 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] (in AppKit) + 128 [0x7fff8ea8bed2] + 2663 _DPSNextEvent (in AppKit) + 685 [0x7fff8ea8c613] + 2663 BlockUntilNextEventMatchingListInMode (in HIToolBox) + 62 [0x7fff8dd53cd3] + 2663 ReceiveNextEventCommon (in HIToolBox) + 356 [0x7fff8dd53e42] + 2663 RunCurrentEventLoopInMode (in HIToolBox) + 209 [0x7fff8dd540a4] + 2663 CFRunLoopRunSpecific (in CoreFoundation) + 290 [0x7fff95dec6b2] + 2557 __CFRunLoopRun (in CoreFoundation) + 1078 [0x7fff95decee6] + ! 2556 __CFRunLoopServiceMachPort (in CoreFoundation) + 195 [0x7fff95de7803] + ! : 2556 mach_msg (in libsystem_kernel.dylib) + 70 [0x7fff93630c42] + ! : 2556 mach_msg_trap (in libsystem_kernel.dylib) + 10 [0x7fff93631686] + ! 1 __CFRunLoopServiceMachPort (in CoreFoundation) + 199 [0x7fff95de7807] + 97 __CFRunLoopRun (in CoreFoundation) + 728 [0x7fff95decd88] + ! 97 __CFRunLoopDoObservers (in CoreFoundation) + 369 [0x7fff95e11921] + ! 97 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ (in CoreFoundation) + 23 [0x7fff95e119b7] + ! 97 __83-[NSWindow _postWindowNeedsDisplayOrLayoutOrUpdateConstraintsUnlessPostingDisabled]_block_invoke_01208 (in AppKit) + 46 [0x7fff8f05a971] + ! 90 _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints (in AppKit) + 738 [0x7fff8ea8f2ac] + ! : 89 -[NSView displayIfNeeded] (in AppKit) + 1830 [0x7fff8ea8fd73]
这告诉我的是,MyApp已经通过main等等,最后进入了一个函数CFRunLoopRunSpecific,然后是__CFRunLoopRun – 从那里(2557)它叫做__CFRunLoopServiceMachPort,它叫做mach_msg,并进入mach_msg_trap(调用一个系统调用)的陷阱,– 当它回来时,堆栈跟踪返回到CFRunLoopRunSpecific,其中调用__CFRunLoopRun,然后调用__CFRunLoopDoObservers等等.
请注意,这不是任何悬挂过程的转折点 – 您可以以任何运行的过程进行采样,并查看该示例中调用的函数.然而,无限循环将一遍又一遍地重复调用某些函数 – 一遍又一遍地会有相同的调用树.当然,这可能意味着一个简单的循环,但这是你可以检查的地方,如果循环不是由于某种原因无限的.不幸的是,这些旋转转储通常相当长,这取决于你所调用的功能,所以可能需要一些时间来检查
行开始处的符号只是表示行的开始 – 没有符号的行表示新线程的开头.的!并且:符号会生成一行,因此您可以轻松查看后续呼叫,即哪些呼叫处于同一级别.此外,|人物也可以使用.
数字表示应用程序在该特定呼叫中花了多长时间 – 它们在样本数量上.采样将采样应用程序每隔几毫秒暂停,并对每个线程检查堆栈帧.如果应用程序仍然在同一个函数中,则该函数为1.