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

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

问题描述

我正在使用多线程应用程序,我想使用GDB进行调试。



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

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

我知道该消息的原因,但我不知道我的线程发生在哪里。回溯真的很有帮助。



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

解决方案

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



以下摘录从gdb手册描述了接收点功能。






5.1.3设置收发点



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




  • catch 事件


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





    • 抛出


      抛出C ++异常。



    • catch




      捕获C ++异常。



    • exec


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



    • fork



      < blockquote>

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



    • vfork



      < blockquote>

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



    • 加载加载libname


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



    • 卸载卸载libname


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




  • tcatch事件


    设置仅为一个停止启用的接收点。捕获点在第一次捕获事件之后自动删除。





使用



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

  *如果您以交互方式调用函数,GDB通常会在函数完成后向您返回控件执行。但是,如果调用引发异常,则调用可能会绕过将控件返回给您的机制,并导致程序中止或简单地继续运行,直到它触发断点,捕获GDB正在侦听或退出的信号。即使您为异常设置了一个接收点,情况就是这样。交互式呼叫中禁用异常捕获点。 

*您不能以交互方式提出异常。

*您无法以交互方式安装异常处理程序。有时候catch不是调试异常处理的最好方式:如果你需要知道一个异常的位置,被提升,最好在调用异常处理程序之前停止,因为在发生任何展开之前可以看到堆栈。如果您在异常处理程序中设置断点,可能不太容易找出引发异常的位置。



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

  / * addr是存储异常标识符的位置。 
id是异常标识符。 * /
void __raise_exception(void ** addr,void * id);

为了使调试器在任何堆栈展开之前捕获所有异常,请在__raise_exception上设置断点(请参阅使用一个条件断点(参见Break条件)取决于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天全站免登陆