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

我正在开发一个多线程应用程序,我想使用 GDB 来调试它。

问题是,我的一个帖子一直没消息:

pure virtual method called
terminate called without an active exception
Abort

I know the cause of that message, but I have no idea where in my thread it occurs. A backtrace would really be helpful.

当我在 GDB 中运行我的应用程序时,每当一个线程被挂起或恢复时,它都会暂停。我希望我的应用程序继续正常运行,直到其中一个线程死亡与该异常,在这一点上,一切应该停止,以便我可以得到一个回溯。

55041 次浏览

在 __pure_virtual 设置断点

您可以尝试使用“ catchpoint”(catch throw)在生成异常时停止调试器。

以下来自 gdb 手册的 节选描述了 catchpoint 特性。


5.1.3设置捕捉点

可以使用捕获点导致调试器因某些类型的程序事件而停止,例如 C++ 异常或加载共享库。使用 catch 命令设置捕捉点。

  • catch 事件

    事件 发生时会停止. event 可以是以下其中一个:

    • throw

      抛出 C + + 异常。

    • catch

      The catching of a C++ exception.

    • exec

      对 exec 的调用。目前仅适用于 HP-UX。

    • fork

      对 fork 的调用。目前仅适用于 HP-UX。

    • vfork

      对 vfork 的调用。目前仅适用于 HP-UX。

    • 加载 或者加载库名

      任何共享库的动态加载,或者库库名的加载。这目前只适用于 HP-UX。

    • 卸载 或者卸载库名

      卸载任何动态加载的共享库,或卸载库库名。这目前只适用于 HP-UX。

  • Tcatch 事件

    设置只为一站启用的捕捉点。捕获点在第一次捕获事件后自动删除。

使用 info break命令列出当前捕捉点。

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

  • 如果以交互方式调用函数,GDB 通常会在函数完成执行后将控制权返回给您。但是,如果调用引发异常,调用可能会绕过将控制返回给您的机制,导致程序要么中止,要么继续运行,直到遇到断点,捕获 GDB 正在侦听的信号,或者退出。即使为异常设置了捕获点,情况也是如此; 在交互式调用中禁用异常捕获点。

  • You cannot raise an exception interactively.

  • You cannot install an exception handler interactively.

有时 catch 并不是调试异常处理的最佳方法: 如果您需要确切地知道异常引发的位置,最好在调用异常处理程序之前停止,因为这样您可以在任何退出发生之前看到堆栈。如果改为在异常处理程序中设置断点,则可能不容易找到引发异常的位置。

要在调用异常处理程序之前停止,您需要对实现有一些了解。在 GNU C + + 的例子中,异常是通过调用一个名为 _ _ rise _ eption 的库函数引发的,该函数具有以下 ANSI C 接口:

/* addr is where the exception identifier is stored.
id is the exception identifier.  */
void __raise_exception (void **addr, void *id);

要使调试器在任何堆栈退出之前捕获所有异常,请在 __raise_exception 上设置一个断点(参见断点、观察点和异常一节)。

使用依赖于 id 值的条件断点(参见中断条件部分) ,可以在引发特定异常时停止程序。当引发许多异常中的任何一个时,可以使用多个条件断点来停止程序。

FWIW,显然,在 gcc 4.1中,适当的函数名已经更改,必须在该函数中设置断点。

纯粹的虚拟

在 gdb 8.3中,只有以下一个对我有用:

break _Unwind_RaiseException

"catch throw" or "break __cxx_throw" didn't work for me.