在GDB中运行应用程序,直到发生异常


102

我正在开发一个多线程应用程序,我想使用GDB对其进行调试。

问题是,我的线程之一一直死于消息:

pure virtual method called
terminate called without an active exception
Abort

我知道该消息的原因,但是我不知道它在线程中出现的位置。回溯确实会有所帮助。

当我在GDB中运行我的应用程序时,每当线程被暂停或恢复时它就会暂停。我希望我的应用程序继续正常运行,直到其中一个线程死于该异常为止,这时所有内容都应停止,以便获得回溯。


GDB暂停时报告什么信号?您应该能够运行handle SIGUSR1 pass noprint nostop
Hasturkun,2009年

Answers:


147

您可以尝试使用“捕获点”(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
scai

5

在__pure_virtual上设置一个断点


在@JeffreyHill答案中,现在称为__cxa_pure_virtual。我不知道该如何检查自己,所以我不想编辑答案。我不打算拒绝投票,但是答案现在可能是错误的,应该由知道正确的人进行编辑。
菲利普·克拉森(PhilippClaßen)

5

FWIW,显然,在gcc 4.1中,相应的函数名称已更改,必须在此函数中设置一个断点。

__cxa_pure_virtual


0

只有以下一项适用于我的gdb 8.3:

break _Unwind_RaiseException

“丢球”或“打破__cxx_throw”对我不起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.