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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1115428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:51:03  来源:igfitidea点击:

Run an Application in GDB Until an Exception Occurs

c++debugginggdbpolymorphismmulticore

提问by Ankur Sethi

I'm working on a multithreaded application, and I want to debug it using GDB.

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

Problem is, one of my threads keeps dying with the message:

问题是,我的一个线程随着消息不断死亡:

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.

我知道该消息的原因,但我不知道它出现在我的线程中的哪个位置。回溯真的很有帮助。

When I run my app in GDB, it pauses every time a thread is suspended or resumed. I want my app to continue running normally until one of the threads dies with that exception, at which point everything should halt so that I can get a backtrace.

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

回答by Dan

You can try using a "catchpoint" (catch throw) to stop the debugger at the point where the exception is generated.

您可以尝试使用“捕获点” ( catch throw) 在生成异常的位置停止调试器。

The following excerptFrom the gdb manual describes the catchpoint feature.

以下摘录自 gdb 手册描述了捕获点功能。



5.1.3 Setting catchpoints

5.1.3 设置捕捉点

You can use catchpoints to cause the debugger to stop for certain kinds of program events, such as C++ exceptions or the loading of a shared library. Use the catch command to set a catchpoint.

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

  • catch event

    Stop when eventoccurs. event can be any of the following:

    • throw

      The throwing of a C++ exception.

    • catch

      The catching of a C++ exception.

    • exec

      A call to exec. This is currently only available for HP-UX.

    • fork

      A call to fork. This is currently only available for HP-UX.

    • vfork

      A call to vfork. This is currently only available for HP-UX.

    • load orload libname

      The dynamic loading of any shared library, or the loading of the library libname. This is currently only available for HP-UX.

    • unload orunload libname

      The unloading of any dynamically loaded shared library, or the unloading of the library libname. This is currently only available for HP-UX.

  • tcatch event

    Set a catchpoint that is enabled only for one stop. The catchpoint is automatically deleted after the first time the event is caught.

  • 捕捉事件

    事件发生时停止。事件可以是以下任何一种:

    • 抛出 C++ 异常。

    • 抓住

      捕获 C++ 异常。

    • 执行

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

    • 叉子

      呼叫分叉。这目前仅适用于 HP-UX。

    • 叉子

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

    • 加载加载 libname

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

    • 卸载卸载 libname

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

  • tcatch 事件

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

Use the info breakcommand to list the current catchpoints.

使用该info break命令列出当前的捕获点。

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

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

  • 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.

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

  • 您不能以交互方式引发异常。

  • 您不能以交互方式安装异常处理程序。

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.

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

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:

要在异常处理程序被调用之前停止,您需要一些实现知识。在 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, set a breakpoint on __raise_exception (see section Breakpoints; watchpoints; and exceptions).

要使调试器在任何堆栈展开之前捕获所有异常,请在 __raise_exception 上设置断点(请参阅断点;观察点;和异常部分)。

With a conditional breakpoint (see section Break conditions) that depends on the value of id, you can stop your program when a specific exception is raised. You can use multiple conditional breakpoints to stop your program when any of a number of exceptions are raised.

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

回答by Steve Folly

Set a breakpoint on __pure_virtual

在 __pure_virtual 上设置断点

回答by Jeffrey Hill

FWIW, apparently, in gcc 4.1, the appropriate function name has changed and one must set a breakpoint in this function.

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

__cxa_pure_virtual

__cxa_pure_virtual