Spindump分析说明?

时间:2012-05-22 20:21:47

标签: objective-c xcode macos

我有一个专注于需要分析的应用程序的spindump集合,但是我不确定如何分析它们。我见过一些其他开发人员能够快速解析这些问题,无论是精神上还是软件,并回到我身边,详细了解挂起的地方等等,我希望能够理解如何正确分析这些。

在哪里可以正确分析几个泵?

2 个答案:

答案 0 :(得分:13)

一般来说:

  • 使用崩溃报告,您将获得堆栈跟踪
  • 使用spindumps,您可以在一段时间内获得多个堆栈跟踪。

有两种情况可能需要检查一个spindump:

  1. 一个无限循环,可能一遍又一遍地调用相同的函数
  2. 死锁。
  3. 第一种情况可以通过多次调用同一函数从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,依此类推。

    请注意,这不是任何挂起过程的一个spindump - 您可以通过这种方式对任何正在运行的进程进行采样,并查看该示例中调用的函数。然而,无限循环会反复调用某些函数 - 反复出现相同的调用树。当然,这可能意味着一个简单的循环,但是如果for循环不是出于某种原因无限的话,那就是你可以检查的地方。不幸的是,这些自旋转储通常很长,取决于你调用的函数,所以可能需要一些时间来检查

    行开头的+号只表示行的开头 - 没有+符号的行表示新线程的开头。的!和:符号形成一条线,因此您更容易看到后续呼叫 - 即哪些呼叫处于同一级别。此外,|字符也可以使用。

    这些数字表示应用在该特定通话中花费的时间 - 它们的样本数量。采样工作使得采样的应用程序每隔几毫秒暂停一次,并检查每个线程的堆栈帧。如果应用程序仍然使用相同的功能,则该功能将获得+1。

答案 1 :(得分:1)

我在Mac Developer Resources搜索“spindump”时发现了这一点。 我从未见过一个,但ReportCrash(8)手册页中提到的这个TechNote似乎向您展示了如何阅读崩溃日志:

https://developer.apple.com/library/mac/#technotes/tn2004/tn2123.html

而ReportCrash(8)提到了Spindump(8),我很抱歉。 https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ReportCrash.8.html

但显然这并没有帮助你。我也会把它留在这里。

希望这能以某种方式帮助某人。