我正在开发一个最近发展成为大型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 ++中引发的每个异常,但如果我不能仅仅对未处理的异常进行破坏,我仍然会发现这种能力很有用。
答案 0 :(得分:5)
您可以在Xcode中快速建立所有C ++抛出条件的中断:
cmd+6
std::out_of_range
<强>更新强>
如果你有很多过滤器,你可能更喜欢:
__cxa_throw
(可能因标准库而异)bt
bt
命令记录回溯。以这种方式配置,它将自动继续。
因此,这只会记录每个引发异常的回溯 - 当程序因未处理的异常而终止时,线索将在最终记录的回溯中(通常是最后一个,除非库重新抛出)。
答案 1 :(得分:1)
在应用程序中,我使用许多c ++异常进行调试,我将“Catch C ++ Exceptions on Throw”关闭,直到我到达应用程序中将引发异常的点,然后我打开该选项并且通常抛出的下一个异常是我正在寻找的。这将比错误的位置更深一些,但堆栈是完整的,所以你可以弄清楚发生了什么。
答案 2 :(得分:0)
检查PLCrashReporter。我们将它与我们的应用程序(它严重依赖于C ++)一起使用,它甚至为C ++代码生成堆栈跟踪。
你可能遇到的唯一问题是当使用本身不是为iOS编写的汇编程序时(Apple的编译器使用R7来保存堆栈帧以追溯不符合官方ARM EBI的符号)