如何使用gdb获取C ++中当前异常的值和类型? [英] How do I get the value and type of the current exception in C++ using gdb?

查看:351
本文介绍了如何使用gdb获取C ++中当前异常的值和类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

已更新






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


目前在gdb中对C ++异常处理(catch
throw and catch catch)有一些限制:



如果以交互方式调用函数,gdb通常将控件返回到
当函数执行完毕。但是,如果该调用引发了
异常,那么该调用可能会绕过将
控制权返回给您的机制,并导致您的程序中止或简单地
继续运行,直到它到达断点,捕获gdb
正在侦听或退出的信号。即使您为异常设置了
的接收点,也是如此。在交互式调用中禁用异常的接收点
。你不能交互地提出异常。
您不能以交互方式安装异常处理程序。有时候catch
不是调试异常处理的最佳方式:如果你需要知道
正好在异常引发的地方,最好在调用
异常处理程序之前停止,因为这样在任何展开之前,您可以看到堆栈
。如果您在
异常处理程序中设置断点,可能不太容易找出
异常的发生位置。



停止在调用异常处理程序之前,您需要一些
的实现知识。在gnu C ++的情况下,通过调用名为__raise_exception的库函数引发异常

具有以下ANSI C接口:

  / * addr是存储异常标识符的位置。 
id是异常标识符。 * /
void __raise_exception(void ** addr,void * id);要使调试器在任何堆栈展开之前捕获所有异常,

在__raise_exception设置断点(请参阅断点;观察点;
和例外)。







p>

这取决于代码和堆栈中的位置。如果你实际上遇到了例外:

  try {....} catch(std :: exception& e) {
//做东西
}

你可能会尝试打印code> e.what(),或查看异常的成员。如果你只是把它当作(...),那么我不知道你能收集什么。



你可以做的另一个处理方法是抓住如果你真的想跟随整个流程,那么'g'中的'throw'也可以捕捉'catch'。

  gdb> catch catch 
gdb> catch throw

这样你就可以在异常被抛出之前得到一个断点,然后您可以走栈来获取有关发生的更多信息。即使你处于另一个断点,你应该能够走上栈(使用向上或向下)来获得异常可见的框架。


gdb allows one to catch exceptions when they're thrown, and when they're caught. But sometimes the line an exception is thrown has no symbols, or a breakpoint is triggered during exception handling. How do I inspect the value of the current exception?

解决方案

Updated


Here's some info from the GDB Manual

There are currently some limitations to C++ exception handling (catch throw and catch catch) in gdb:

If you call a function interactively, gdb normally returns control to you when the function has finished executing. If the call raises an exception, however, the call may bypass the mechanism that returns control to you and cause your program either to abort or to simply continue running until it hits a breakpoint, catches a signal that gdb is listening for, or exits. This is the case even if you set a catchpoint for the exception; catchpoints on exceptions are disabled within interactive calls. You cannot raise an exception interactively. You cannot install an exception handler interactively. Sometimes catch is not the best way to debug exception handling: if you need to know exactly where an exception is raised, it is better to stop before the exception handler is called, since that way you can see the stack before any unwinding takes place. If you set a breakpoint in an exception handler instead, it may not be easy to find out where the exception was raised.

To stop just before an exception handler is called, you need some knowledge of the implementation. In the case of gnu C++, exceptions are raised by calling a library function named __raise_exception which has the following ANSI C interface:

     /* 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,

set a breakpoint on __raise_exception (see Breakpoints; Watchpoints; and Exceptions).


That said

It depends on the code and where you are in the stack. If you actually caught the exception as in :

try { .... } catch (std::exception &e) {
   //do stuff
}

You could probably try printing e.what(), or look at the members of the exception. If you just caught it as (...) then I'm not sure what you'd be able to gather.

Another handling thing you could do is to catch 'throw' in gdb and catch 'catch' as well if you really want to follow the whole flow.

gdb> catch catch  
gdb> catch throw

This way you will get a breakpoints right before exceptions are thrown and right as they are caught, you could then walk the stack to gain more information about what was going on. Even if you are in another break point you should be able to walk up the stack (using up or down) to get the frame in which the exception is visible.

这篇关于如何使用gdb获取C ++中当前异常的值和类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆