如何从 obj-c / ios 中的堆栈跟踪中获取源代码行

Posted

技术标签:

【中文标题】如何从 obj-c / ios 中的堆栈跟踪中获取源代码行【英文标题】:How to get source code line from stack trace in obj-c / ios 【发布时间】:2012-08-21 22:20:08 【问题描述】:

我使用NSSetUncaughtExceptionHandler 将堆栈跟踪打印到iPhone 中的本地文件,该文件将在应用程序下次启动时发送到我们的服务器。然后我可以检查异常数据并修复错误。 在某些崩溃中,我有模块名称和引发异常的函数,这些都很容易。 但大多数情况下我有这样的事情:

"4   libc++abi.dylib 0x35bba3c5 _ZL19safe_handler_callerPFvvE + 76",
"5   libc++abi.dylib 0x35bba451 _ZdlPv + 0",
"6   libc++abi.dylib 0x35bbb825 __cxa_current_exception_type + 0",
"7   libobjc.A.dylib 0x37bab2a9 objc_exception_rethrow + 12",
"8   CoreFoundation  0x3575a50d CFRunLoopRunSpecific + 404"

例如原因:

*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array

但是我的应用程序中有几十个数组,所以我需要帮助来使用从堆栈跟踪中获得的数据来查找引发异常的特定行。

有没有人知道来自 Apple 或其他方面的好文章/教程,我可以在其中学习解码堆栈跟踪中的数字以找到源代码中的问题行。 提前致谢!

【问题讨论】:

我建议您阅读本教程My App Crashed 这是我写的一篇使用atos翻译的帖子。我很少再使用这种方法,因为现在我只是将崩溃日志复制到 Xcode Organizer 中,它可以很好地进行符号化。无论如何,它可能会有所帮助:saveme-dot-txt.blogspot.com/2011/04/… 也许 GTMStackTrace 有帮助 code.google.com/p/google-toolbox-for-mac/source/browse/trunk/… Mike M,你把崩溃日志复制到 XCode Organizer 是什么意思? 此链接显示如何使用 lldb 的 image lookupsource list 查找违规代码行:***.com/questions/18112842/… 【参考方案1】:

我强烈建议在 Xcode 中启用异常断点。它将在使您的应用程序崩溃的确切行上停止执行您的代码。所以你不必担心是哪个数组导致崩溃。 *** -[__NSArrayI objectAtIndex:]:空数组的索引 0 超出范围

添加异常断点

    转到 Xcode 上的断点部分 点击该部分底部的加号唱歌 选择添加异常断点

【讨论】:

我相信 OP 正在寻找作为崩溃报告发送到服务器/数据库的堆栈跟踪中的行号,即她没有在 XCode 中进行测试并且无权访问其断点资源.【参考方案2】:

我还不知道如何从堆栈跟踪中获取行号,但是在我想要打印行号的代码中的某些点上,我使用了以下代码片段:

NSLog(@"%s line=%d", __func__, __LINE__);

这将给出以下输出:

2013-04-01 00:16:46.393 MyApp[847:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] line=29

如果您熟悉 Log4J 框架,我建议您查看 Lumberjack 框架,该框架在各种项目中对我很有帮助。

https://github.com/robbiehanson/CocoaLumberjack

虽然这可能无法直接回答您的问题,但它只是一个提醒。

【讨论】:

【参考方案3】:

打印存储在异常中的堆栈跟踪,即[exception callStackSymbols][exception callStackReturnAddresses]。在 Apple 自 ios 5 以来的崩溃日志中,这在顶部显示为“Last Exception Backtrace”。

您看到的是重新抛出异常时的调用堆栈,对于像try...finally 这样简单的事情都会发生这种情况。我不确定 Apple 做出此更改的确切原因(可能是为了使运行循环异常安全?),但你去吧。

【讨论】:

【参考方案4】:

在 catch 块中设置断点,一旦代码流停止,您可以使用 gdb 命令,例如 'bt'。

【讨论】:

以上是关于如何从 obj-c / ios 中的堆栈跟踪中获取源代码行的主要内容,如果未能解决你的问题,请参考以下文章

iOS:如何获取未处理的 std::exception 的堆栈跟踪?

如何从像 Asp.Net 这样的堆栈跟踪中获取“源错误”?

从核心转储中获取堆栈跟踪

如何在python中获取嵌套异常的堆栈跟踪?

Obj-C:从导航控制器中的 detailViewController 传回参数

从堆栈跟踪中获取更多详细信息