在GDB中运行应用程序,直到发生异常 [英] Run an Application in GDB Until an Exception Occurs

查看:264
本文介绍了在GDB中运行应用程序,直到发生异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题是,我的一个线程不断死亡的消息: / p>

 纯虚拟方法
终止调用时没有活动异常
中止

我知道该消息的原因,但我不知道在我的线程中发生了什么。



当我在GDB中运行我的应用程序时,每次线程被暂停或恢复时暂停。我想让我的应用程序继续正常运行,直到其中一个线程死于该异常,此时一切都应该停止,以便我可以得到一个回溯。

解决方案

您可以尝试使用catchpoint( catch throw )在生成异常的地方停止调试器。



以下摘录从gdb手册中描述




5.1.3设置接受点



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




  • 捕获事件 b


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





    • throw


      抛出C ++异常。



    • p>


      捕获C ++异常。



    • exec


      调用exec。



    • blockquote>

      调用fork。目前只适用于HP-UX。



    • vfork



      < blockquote>

      调用vfork。目前只适用于HP-UX。



    • 载入载入libname


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



    • 卸载 >


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




  • tcatch活动


    设置仅启用一个停靠点的接收点。





使用 info break 命令列出当前的接收点。



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

  *如果你以交互方式调用函数,GDB通常在函数完成后返回控制权执行。但是,如果调用引发了异常,调用可能会绕过向您返回控制的机制,并导致程序中止或简单地继续运行,直到遇到断点,捕获GDB正在侦听的信号或退出。即使您为异常设置了一个catchpoint,也是如此;在交互式呼叫中禁用异常的catchpoints。 

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

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

有时候catch不是调试异常处理的最好方法:如果你需要知道异常是提出来的,最好是在调用异常处理程序之前停止,因为这样你可以在任何解开之前看到堆栈。如果您在异常处理程序中设置断点,可能不容易找出异常发生的位置。



要在调用异常处理程序之前停止,你需要一些知识的实现。在GNU C ++的情况下,通过调用名为__raise_exception的库函数来引发异常,该函数具有以下ANSI C接口:

  * addr是存储异常标识符的地方。 
id是异常标识符。 * /
void __raise_exception(void ** addr,void * id);为了使调试器在任何堆栈展开之前捕获所有异常,请在__raise_exception上设置断点(请参阅参考资料)(参见下面的示例):



<



使用取决于id值的条件断点(请参阅断点条件),可以在特定的异常被引发。当出现多个异常时,可以使用多个条件断点来停止程序。


I'm working on a multithreaded application, and I want to debug it using 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.

解决方案

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

The following excerpt From the gdb manual describes the catchpoint feature.


5.1.3 Setting catchpoints

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.

  • catch event

    Stop when event occurs. 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 or load libname

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

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

Use the info break command to list the current catchpoints.

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 section Breakpoints; watchpoints; and exceptions).

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.

这篇关于在GDB中运行应用程序,直到发生异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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