Answers:
您可以尝试使用“捕获点”(catch throw
)在生成异常的位置停止调试器。
以下摘录自gdb手册,介绍了捕捉点功能。
5.1.3设置捕捉点
您可以使用捕捉点使调试器针对某些类型的程序事件(例如C ++异常或共享库的加载)而停止。使用catch命令设置捕捉点。
赶上事件
事件发生时停止。事件可以是以下任意一个:
扔
抛出C ++异常。
抓住
捕获C ++异常。
执行
调用执行程序。当前仅适用于HP-UX。
叉子
拨叉。当前仅适用于HP-UX。
叉
调用vfork。当前仅适用于HP-UX。
加载或加载libname
动态加载任何共享库,或加载库libname。当前仅适用于HP-UX。
卸载或卸载libname
卸载任何动态加载的共享库,或卸载库libname。当前仅适用于HP-UX。
tcatch事件
设置仅启用一站的捕获点。第一次捕获事件后,捕获点将自动删除。
使用info break
命令列出当前的捕获点。
当前,GDB中对C ++异常处理(捕获抛出和捕获捕获)有一些限制:
如果以交互方式调用函数,则GDB通常在函数完成执行后将控制权返回给您。但是,如果调用引发异常,则该调用可能会绕过将控制权返回给您的机制,并导致您的程序中止或继续运行,直到遇到断点,捕获到GDB正在侦听或退出的信号为止。即使您为异常设置了捕捉点,也是如此。交互式调用中禁用了异常的捕获点。
您不能以交互方式引发异常。
您不能以交互方式安装异常处理程序。
有时catch并不是调试异常处理的最佳方法:如果您需要确切知道引发异常的位置,最好在调用异常处理程序之前停止,因为这样您可以在展开任何操作之前先查看堆栈。如果改为在异常处理程序中设置断点,则可能不容易找出引发异常的位置。
要在调用异常处理程序之前停止,您需要一些实现知识。对于GNU C ++,通过调用具有以下ANSI C接口的名为__raise_exception的库函数来引发异常:
/* addr is where the exception identifier is stored.
id is the exception identifier. */
void __raise_exception (void **addr, void *id);
要使调试器在展开任何堆栈之前捕获所有异常,请在__raise_exception上设置一个断点(请参见“断点;观察点和异常”部分)。
使用取决于id值的条件断点(请参见“中断条件”部分),可以在引发特定异常时停止程序。当引发任何数量的异常时,您可以使用多个条件断点来停止程序。
catch throw std::runtime_exception
。
在__pure_virtual上设置一个断点
handle SIGUSR1 pass noprint nostop