如何理解这个崩溃日志

12

我在我的首个 Mac 应用商店应用程序中遇到了以下崩溃报告(来自 ITC)。 利用 Stackoverflow 上的知识,我尝试对此日志进行符号化,但是(使用 atos 和 otool)我只能读取最后的 20 行(也就是 start (in My App) + 52)。 我真的不知道如何解释上面的行,以及如何找到崩溃原因。

Process:         My App [270]
Identifier:      com.mycompany.myapp
Version:         1.0.0 (1.0.0)
App Item ID:     568750000
App External ID: 11410000
Code Type:       X86-64 (Native)
Parent Process:  launchd [143]
User ID:         501

Date/Time:       2012-11-07 19:21:11.365 -0200
OS Version:      Mac OS X 10.8.2 (12C60)
Report Version:  10

Per-App Interval Since Last Report:  1232 sec
Per-App Crashes Since Last Report:   1

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x00007fff877a5256 objc_msgSend + 22
1   com.apple.AppKit                0x00007fff8dac6e27 -[NSOutlineView _delegate_isGroupRow:] + 66
2   com.apple.AppKit                0x00007fff8da46878 -[NSTableView _isGroupRow:] + 81
3   com.apple.AppKit                0x00007fff8da41fad -[NSTableView _isSourceListGroupRow:] + 56
4   com.apple.AppKit                0x00007fff8da418e8 -[NSTableView rectOfRow:] + 288
5   com.apple.AppKit                0x00007fff8da5b3cb _NSTVVisibleRowsForUpdate + 296
6   com.apple.AppKit                0x00007fff8da5aa85 -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 96
7   com.apple.AppKit                0x00007fff8da5a8a1 -[NSTableRowData updateVisibleRowViews] + 119
8   com.apple.AppKit                0x00007fff8da6e463 -[NSTableRowData _idleUpdateVisibleRows] + 66
9   com.apple.CoreFoundation        0x00007fff87547da4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
10  com.apple.CoreFoundation        0x00007fff875478bd __CFRunLoopDoTimer + 557
11  com.apple.CoreFoundation        0x00007fff8752d099 __CFRunLoopRun + 1513
12  com.apple.CoreFoundation        0x00007fff8752c6b2 CFRunLoopRunSpecific + 290
13  com.apple.HIToolbox             0x00007fff830a30a4 RunCurrentEventLoopInMode + 209
14  com.apple.HIToolbox             0x00007fff830a2e42 ReceiveNextEventCommon + 356
15  com.apple.HIToolbox             0x00007fff830a2cd3 BlockUntilNextEventMatchingListInMode + 62
16  com.apple.AppKit                0x00007fff8d8d8613 _DPSNextEvent + 685
17  com.apple.AppKit                0x00007fff8d8d7ed2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
18  com.apple.AppKit                0x00007fff8d8cf283 -[NSApplication run] + 517
19  com.apple.AppKit                0x00007fff8d873cb6 NSApplicationMain + 869
20  com.mycompany.myapp             0x000000010f29ce1c 0x10f29b000 + 7708

这是分段错误,可能不是发生在你的某个方法中。所以你以某种方式使表视图处于不一致的状态。 - Ramy Al Zuhouri
谢谢您的帮助,但我的应用程序中有大量的TableView和OutlineView。如果不确定这个报告所属的窗口,那么这份报告对我来说完全没有用处(就像其他来自OSX的报告一样 :( )。 - Tomasz Wojtkowiak
1个回答

46

阅读不属于您代码的堆栈帧通常近乎于读茶叶,但在这种情况下,发生了什么很清楚。

我将为您朗读崩溃日志,并在读取时进行翻译。

堆栈是从底部向上构建的(就像现实世界中的堆栈一样)。 我将直接切入主题:

10  com.apple.CoreFoundation        0x00007fff875478bd __CFRunLoopDoTimer + 557
9   com.apple.CoreFoundation        0x00007fff87547da4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
计时器触发。
8   com.apple.AppKit                0x00007fff8da6e463 -[NSTableRowData _idleUpdateVisibleRows] + 66
7   com.apple.AppKit                0x00007fff8da5a8a1 -[NSTableRowData updateVisibleRowViews] + 119
6   com.apple.AppKit                0x00007fff8da5aa85 -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 96
5   com.apple.AppKit                0x00007fff8da5b3cb _NSTVVisibleRowsForUpdate + 296
在这个计时器中(可能在空闲时间设置),表视图尝试更新其对哪些行是可见的认知。
(最后一帧澄清了它正在更新哪些行是可见的,而不是更新已经可见的行。您可以从函数名称的措辞中得出这一点。)
4   com.apple.AppKit                0x00007fff8da418e8 -[NSTableView rectOfRow:] + 288
为了确定一行是否可见,视图需要找出该行在其范围内的位置(可能与滚动视图中的可见矩形相交)。
为此,表格视图正在尝试找出该行的特征:
3   com.apple.AppKit                0x00007fff8da41fad -[NSTableView _isSourceListGroupRow:] + 56
这是一个源代码列表组的行吗?
2   com.apple.AppKit                0x00007fff8da46878 -[NSTableView _isGroupRow:] + 81
这是任何小组的行吗?
1   com.apple.AppKit                0x00007fff8dac6e27 -[NSOutlineView _delegate_isGroupRow:] + 66

让我们询问代表。

0   libobjc.A.dylib                 0x00007fff877a5256 objc_msgSend + 22
尝试发送消息。这是进程崩溃的位置。
因此,在大纲视图尝试向其委托发送消息时发生了崩溃。
由此,我们可以得出三个事实:
1. 相关的视图是一个大纲视图,而不是非大纲表格视图。(Frame #1 证明了这一点。普通的表格视图不是 NSOutlineView。) 这可能足以确定涉及的视图,但如果无法确定,也没关系,因为我们有另一个事实可能会缩小范围。
2. 相关的大纲视图具有委托。这单独就可能确定涉及的大纲视图,但如果无法确定,也没关系,因为问题根本不在视图上。
3. 问题在于作为视图委托的对象被拥有的不充分。它在大纲视图发送我们在堆栈跟踪中看到的消息之前过早死亡。
使用 Instruments 的 Zombies 模板确定大纲视图正在尝试与哪个对象交流,并查看该对象历史记录,找到导致其死亡的不当或不平衡释放。您可能需要在某处添加该对象的强拥有权。

非常感谢您的出色解释。这让我更好地理解了这个日志。现在我会尝试找到错误所在。 - Tomasz Wojtkowiak
5
Peter,这是我遇到过的最有帮助的帖子之一!与我所遇到的情况完全相同,只是使用的是简单的表格视图而不是大纲视图。我的错误在于,在让ARC释放我的视图控制器之前,我忘记将表视图的代理和数据源设置为nil。 - Chuck H
我的栈跟踪中没有明确的“_delegate_”线索,但最终它是一个委托问题。我将视图控制器推入导航堆栈并将其设置为标签栏的委托。然后我忘记在弹出该视图控制器之前将委托设置为nil。然后当我点击标签栏时,砰,因为它试图访问不再存在的视图控制器。对我来说,在这些情况下没有抛出异常很奇怪。 - Murray Sagal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接