如何使用gdb在C++中获取当前异常的值和类型?

Mat*_*ner 28 c++ debugging gdb exception inspection

gdb允许一个人在被抛出时捕获异常,并在被捕获时捕获异常.但有时抛出异常的行没有符号,或者在异常处理期间触发断点.如何检查当前异常的值?

UpA*_*dam 8

更新


以下是GDB手册中的一些信息

目前gdb中的C++异常处理(catch throw和catch catch)存在一些限制:

如果以交互方式调用函数,gdb通常会在函数执行完毕后向您返回控制权.如果调用引发了异常,然而,呼叫可能越过交还控制权的机制,让程序结束或仅仅只是继续执行,直到遇到一个断点,捕获到一个信号,即GDB被监听,或退出.即使您为异常设置了一个catchpoint,情况也是如此; 在交互式调用中禁用异常的捕获点.您不能以交互方式提出异常.您无法以交互方式安装异常处理程序.有时catch不是调试异常处理的最佳方法:如果您需要确切地知道引发异常的位置,最好在调用异常处理程序之前停止,因为这样您可以在任何展开之前看到堆栈.如果在异常处理程序中设置断点,则可能不容易找出引发异常的位置.

要在调用异常处理程序之前停止,您需要了解实现.在gnu C++的情况下,通过调用名为__raise_exception的库函数来引发异常,该函数具有以下ANSI C接口:

     /* addr is where the exception identifier is stored.
        id is the exception identifier.  */
     void __raise_exception (void **addr, void *id); To make the debugger catch all exceptions before any stack unwinding takes place,
Run Code Online (Sandbox Code Playgroud)

在__raise_exception上设置断点(请参阅断点;观察点;以及异常).


那就是说

这取决于代码以及您在堆栈中的位置.如果您确实捕获了异常,如:

try { .... } catch (std::exception &e) {
   //do stuff
}
Run Code Online (Sandbox Code Playgroud)

您可以尝试打印e.what(),或查看异常的成员.如果你只是把它当成(...)那么我不确定你能收集到什么.

您可以做的另一个处理事情是在gdb中捕获'throw'并捕获'catch',如果您真的想要遵循整个流程.

gdb> catch catch  
gdb> catch throw
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以在抛出异常之前获得断点,然后在捕获异常时获得断点,然后您可以遍历堆栈以获取有关正在发生的事情的更多信息.即使你处于另一个断点,你也应该能够向上走(使用向上或向下)以获得可以看到异常的帧.


Tom*_*mey 7

在撰写时(2013年),早期的答案是正确的,但从那以后gdb和libstdc ++已经改变.

libstdc ++现在有一些钩子让gdb与异常系统更好地交互.特别是,现在有足够的信息暴露给gdb,$_exception以便为用户提供便利变量.此变量保存抛出的异常.它仅在捕获异常的地方有效; 您可以停止使用catch catch.

有关详细信息,请参阅手册中的页面.