我可以获得未处理(目标)C ++异常的堆栈跟踪吗?

时间:2012-02-29 21:15:08

标签: c++ objective-c xcode exception

我正在开发一个最近发展成为大型C ++库的iOS应用程序。 C ++不是我的强项,我对异常感到沮丧。我正在寻找的是一种将堆栈跟踪到(未处理的)异常抛出的站点的方法。我会说“未处理”限定符是可选的;虽然未处理的异常是理想的,但我会决定打破任何异常抛出,但最好的办法是。

我目前得到的是没用的。假设我在callstack上面没有任何适当的异常处理程序,我做了类似

的操作
std::vector<int> my_vector;
my_vector.at(40) = 2; // Throws std::out_of_range

该应用程序将在main()中断,我将收到一条日志消息,说“终止称为抛出异常”。没用。

将通用try / catch块放在callstack的上方也无济于事,因为在异常处理期间,callstack在catch块的点处被展开,让我无视异常的实际原因。这也适用于提供我自己的terminate_handler。断言更有用,但它们要求我在某种程度上预测错误条件,这是我不能总是这样做的。我仍然希望调试器能够介入,即使意外的异常使它超过我的先发制人assert()

我想要避免的是必须包装每个可能在try / catch块中引发异常的调用,只是为了让堆栈跟踪错误。在运行时,我真的对捕获这些异常不感兴趣。当它们发生时,意味着程序执行中存在致命缺陷,并且它无法正常继续。我只是想收到通知,以便我可以确定原因并修复问题,这样就不会再发生了。

<小时/>

在Objective C中,我可以在objc_exception_throw上放置一个符号断点,任何时候我搞砸了什么,我会立即中断执行并呈现一个很好的堆栈跟踪,所以我知道问题出在哪里。非常有帮助。

我意识到这种行为真的很有用,因为两种语言之间的异常处理存在哲学上的差异。 Objective C异常仅用于表示不可恢复的错误。常规错误处理的任务是通过错误返回码完成的。这意味着任何 Objective C异常都是开发人员断点的理想选择。

C ++似乎对Exceptions有不同的用法。它们用于处理致命错误例程错误(至少在我正在使用的第三方库中)。这意味着我可能实际上并不想打破C ++中引发的每个异常,但如果我不能仅仅对未处理的异常进行破坏,我仍然会发现这种能力很有用。

3 个答案:

答案 0 :(得分:5)

您可以在Xcode中快速建立所有C ++抛出条件的中断:

  • cmd+6
  • + ”按钮 - &gt;添加异常断点
    • C ++ - &gt; std::out_of_range
    • On Throw

<强>更新

如果你有很多过滤器,你可能更喜欢:

  • 创建符号断点
  • 符号= __cxa_throw(可能因标准库而异)
  • 动作&gt;调试器命令= bt
  • 在eval = On
  • 后自动继续

bt命令记录回溯。以这种方式配置,它将自动继续。

因此,这只会记录每个引发异常的回溯 - 当程序因未处理的异常而终止时,线索将在最终记录的回溯中(通常是最后一个,除非库重新抛出)。

答案 1 :(得分:1)

在应用程序中,我使用许多c ++异常进行调试,我将“Catch C ++ Exceptions on Throw”关闭,直到我到达应用程序中将引发异常的点,然后我打开该选项并且通常抛出的下一个异常是我正在寻找的。这将比错误的位置更深一些,但堆栈是完整的,所以你可以弄清楚发生了什么。

答案 2 :(得分:0)

检查PLCrashReporter。我们将它与我们的应用程序(它严重依赖于C ++)一起使用,它甚至为C ++代码生成堆栈跟踪。

你可能遇到的唯一问题是当使用本身不是为iOS编写的汇编程序时(Apple的编译器使用R7来保存堆栈帧以追溯不符合官方ARM EBI的符号)