如何最好地调试 objc_msgSend 中的崩溃?

Posted

技术标签:

【中文标题】如何最好地调试 objc_msgSend 中的崩溃?【英文标题】:How best to debug a crash within objc_msgSend? 【发布时间】:2010-11-22 10:20:35 【问题描述】:

NSAutoreleasePool 耗尽时发生崩溃。据推测,池正在尝试解除分配已被另一段代码过早释放的对象。我的崩溃发生在objc_msgSend 中间,因为它试图向一个不再存在的对象发送消息。

鉴于堆栈状态,我可以使用哪些提示/技巧/进程/gdb 命令来获取有关相关对象和/或发生非法释放的点的信息?

【问题讨论】:

【参考方案1】:

如果您有预感这是过早删除,请让僵尸确认您的假设,然后调试正在发生的事情。当您启用僵尸时,对象并没有真正被销毁,而是设置为僵尸状态,这有助于您在调用 dealloc 后检测它们何时被访问。阅读更多来自NSZombieEnabled

【讨论】:

此外,您可以使用 Instruments 的 Object Alloc 工具来跟踪提前释放的对象的保留/释放事件。问题不是自动释放池的 -release,而是一些先前的 -release,通常。【参考方案2】:

关于这种崩溃的权威文章:http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html

【讨论】:

【参考方案3】:

如果您使用 NSZombieEnabled,您至少可以弄清楚该对象是什么类。

【讨论】:

虽然正确,但 tequilatango 的回答提供了答案以及一些有用的细节。 非常正确。我至少可以提供外部信息的链接。【参考方案4】:

我在objc_msgSend 中遇到了似乎是崩溃的情况。更奇怪的是application:didFinishLaunchingWithOptions: 在所谓的崩溃发生之前甚至都没有到达!

在我的情况下,崩溃结果是我无意中在内存地址上设置了一个断点,该内存地址在我的任何代码到达之前就被调用了。

在尝试解决这个问题大约一个小时后,我取消检查断点,运行代码,然后继续我的一天,假装它从未发生过......

【讨论】:

以上是关于如何最好地调试 objc_msgSend 中的崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

RestKit 在 RKManagedObjectRequestOperation objc_msgSend 期间崩溃

Swift 崩溃 libobjc.A.dylib objc_msgSend

如何最好地实现简单的崩溃/错误报告?

什么情况下会出现sigabrt崩溃,如何调试

当我的应用程序在野外崩溃时,如何提高调试数据的质量?

iOS之深入解析消息转发objc_msgSend的应用场景