遇到崩溃报告问题 - EXC_BAD_ACCESS

4

好的,我收到了我的一个应用程序的崩溃报告,但是我发誓我百分之百地感到困惑。

以下是它的“核心”部分:

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

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000

VM Regions Near 0:
--> 
    __TEXT                 0000000100000000-0000000100015000 [   84K] r-x/rwx SM=COW  /Applications/MY_APP/Contents/MacOS/MY_APP

Application Specific Information:
objc[337]: garbage collection is ON

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib               0x00007fff90128650 strlen + 16
1   MY_BUNDLE_ID                    0x0000000100008f12 0x100000000 + 36626
2   MY_BUNDLE_ID                    0x000000010000b435 0x100000000 + 46133
3   MY_BUNDLE_ID                    0x0000000100003c90 0x100000000 + 15504
4   com.apple.CoreFoundation        0x00007fff9065147a _CFXNotificationPost + 2554
5   com.apple.Foundation            0x00007fff8e5fe846 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64
6   com.apple.AppKit                0x00007fff9a7894a7 -[NSTableView textDidChange:] + 377
7   com.apple.CoreFoundation        0x00007fff9065147a _CFXNotificationPost + 2554
8   com.apple.Foundation            0x00007fff8e5fe846 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64
9   com.apple.AppKit                0x00007fff9a15c260 -[NSTextView(NSSharing) didChangeText] + 339
10  com.apple.AppKit                0x00007fff9a7f8381 _NSDoUserReplaceForCharRange + 390
11  com.apple.AppKit                0x00007fff9a7f85b1 _NSDoUserDeleteForCharRange + 38
12  com.apple.AppKit                0x00007fff9a7e1e72 -[NSTextView(NSKeyBindingCommands) deleteBackward:] + 440
13  com.apple.AppKit                0x00007fff9a18a1cc -[NSResponder doCommandBySelector:] + 75
14  com.apple.AppKit                0x00007fff9a18a02e -[NSTextView doCommandBySelector:] + 197
15  com.apple.AppKit                0x00007fff9a20cf4e -[NSKeyBindingManager(NSKeyBindingManager_MultiClients) interpretEventAsCommand:forClient:] + 2200
16  com.apple.AppKit                0x00007fff9a20c3bb -[NSTextInputContext handleEvent:] + 939
17  com.apple.AppKit                0x00007fff9a20bf87 -[NSView interpretKeyEvents:] + 183
18  com.apple.AppKit                0x00007fff9a158f67 -[NSTextView keyDown:] + 723
19  com.apple.AppKit                0x00007fff9a374120 -[NSWindow sendEvent:] + 9687
20  com.apple.AppKit                0x00007fff9a36f744 -[NSApplication sendEvent:] + 5761
21  com.apple.AppKit                0x00007fff9a2852fa -[NSApplication run] + 636
22  com.apple.AppKit                0x00007fff9a229cb6 NSApplicationMain + 869
23  MY_BUNDLE_ID                        0x0000000100002014 0x100000000 + 8212

你有没有想法出了什么问题?或者你能指引我正确的方向吗?


另外:

有人能指导我如何使例如0x00007fff90128650更具意义,并使其(在某些未来的崩溃报告中)显示函数名称吗?


你需要对这个崩溃报告进行符号化,以便查看与你自己的代码相关的引用。堆栈跟踪的第1、2和3行来自你自己的应用程序。一旦你对这个报告进行符号化,你就会准确地看到哪一行代码导致了问题。 - rmaddy
@rmaddy 那我应该怎么做呢?我承认我对利用崩溃报告几乎一无所知,能否给我一些指导或者指向一些参考资料都行。非常感谢! :-) - Dr.Kameleon
@rmaddy 非常感谢!我现在正在学习它。 - Dr.Kameleon
抱歉,我一直关注iOS,忽略了您的帖子标记为OS X。恐怕我不知道如何在OS X中实现这一点。尽管这可能只是将崩溃报告拖到Xcode组织器窗口中就能解决。在设备标签下,有一个设备日志部分。把日志放在那里。这需要您拥有包含该日志的应用程序的存档。 - rmaddy
@Dr.Kameleon 请看一下 http://boredzo.org/blog/archives/2009-04-24/symbolicator-101 - Parag Bafna
显示剩余2条评论
3个回答

13

您的崩溃日志提供了许多信息: 首先,由于您尝试访问程序中的地址0,而内核不允许,因此导致了崩溃。

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000

看,你得到了一个分段错误,因为它开始的地址是0x00,就像你直接访问了一个0/空指针一样。

char* adress = 0;
printf("get %p", adress); // will output 0x0
printf("get %p", adress[0]); // will make a EXC_BAD_ACCESS

你真的应该专注于这个。

从崩溃堆栈中可以看出三件有趣的事情:

6   com.apple.AppKit                0x00007fff9a7894a7 -[NSTableView textDidChange:] + 377
 5   com.apple.Foundation            0x00007fff8e5fe846 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64
    0   libsystem_c.dylib               0x00007fff90128650 strlen + 16
[textDidChange]是导致崩溃的最后一个调用,顺便说一下,当[textDidChange]被触发时,你正在发送通知。而实际导致崩溃的最后一行是:strlen + 16,因为有些东西认为它可以从有效指针地址获取字符长度,但实际上并非如此。
根据我看来,你应该检查你发送到通知中的内容。
_NSDoUserReplaceForCharRange
  _NSDoUserDeleteForCharRange

当你深入分析栈崩溃时,似乎它出现在将单元格插入/删除到表视图控制器中时。您应该检查是否有人推送了无效数据,或者没有按照预期的方式使用编辑单元格。

所以这是简要概括: 1. 有人编辑了tableViewCell,但没有插入或代码没有插入应该插入的内容。 2. 你发送了一个带有无效数据的通知。 3. 当strlen(invalid_dataStructure)被触发时,会导致应用程序崩溃。

顺便说一句,我只是“猜测”,因为我不知道您的代码实现。但我希望它能给您的调试会话提供很多线索。


0

我尝试打开图形重的应用程序(如pymol和coot)时,出现了非常相似的崩溃报告(见下文)

后来我发现,如果我断开我的Mac与外部显示器的连接,这些程序就能工作。我使用的是一个USB-HDMI连接器 - 显然这是个坏主意。我刚刚购买了一个microUSB-HDMI连接器,我希望它会更好地运行。如果我只使用我的Mac书本自己的显示器,那么这些程序也会运行。

Time Awake Since Boot: 19000 seconds
Time Since Wake:       110 seconds

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

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000

VM Regions Near 0:
--> 
    __TEXT                 0000000100000000-0000000100cff000 [ 13.0M] r-x/rwx SM=COW  /Applications/MacPyMOL.app/Contents/MacOS/MacPyMOL

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.apple.opengl                0x00007fff8333857c CGLDescribeRenderer + 79
1   com.schrodinger.macpymol        0x000000010083c5b4 CheckOpenGLCaps + 484
2   com.schrodinger.macpymol        0x000000010084cd8c -[PyMOLOpenGLView awakeFromNib] + 1420
3   com.apple.CoreFoundation        0x00007fff8a10785f -[NSSet makeObjectsPerformSelector:] + 223
4   com.apple.AppKit                0x00007fff88b935cd -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] + 1216
5   com.apple.AppKit                0x00007fff886a3605 loadNib + 384
6   com.apple.AppKit                0x00007fff88c14749 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:options:withZone:ownerBundle:] + 727
7   com.apple.AppKit                0x00007fff88c14ca8 +[NSBundle(NSNibLoadingInternal) _loadNibFile:externalNameTable:options:withZone:] + 150
8   com.apple.AppKit                0x00007fff886a2bc0 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 631
9   com.schrodinger.macpymol        0x000000010084d77b main + 1499
10  com.schrodinger.macpymol        0x0000000100007494 start + 52

0
通常问题在于您需要一个“保留”属性。 您需要启用调试模式下的Zombies。 在xCode 4中单击“编辑方案”->“诊断”->“启用僵尸对象” 当崩溃时,它将在控制台中显示您尝试访问的“已删除”对象。 这应该会有所帮助。 您将看到类似于以下内容的内容:
2010-01-25 14:35:24.840 MyApplication[1393:20b] *** -[CFString retain]: message sent to deallocated instance 0x42a5060

您还可以启用“Malloc日志记录”,在崩溃后在调试控制台中输入以下命令:

shell malloc_history 1393 0x42a5060

在那里你可以找到所有的分配/释放堆栈。只需查看释放和分配命令。


我所拥有的仅是客户发来的崩溃报告。问题在于这个应用程序在我的设备上运行良好,因此实际上没有什么可以“看到”的东西。 - Dr.Kameleon
对我来说,最好的方法是询问复现步骤并尝试在本地进行复现。 - Remizorrr
通常问题是你需要一个"retain"属性。 实际上,这并不是因为异常代码:KERN_INVALID_ADDRESS at 0x0000000000000000 确实没有指向垃圾指针值。 - Mr Bonjour

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