問題描述
我正在開發(fā)一個(gè)多線程應(yīng)用程序,我想使用 GDB 調(diào)試它.
I'm working on a multithreaded application, and I want to debug it using GDB.
問題是,我的一個(gè)線程不斷地隨著消息而死:
Problem is, one of my threads keeps dying with the message:
pure virtual method called
terminate called without an active exception
Abort
我知道該消息的原因,但我不知道它出現(xiàn)在我的線程中的哪個(gè)位置.回溯真的很有幫助.
I know the cause of that message, but I have no idea where in my thread it occurs. A backtrace would really be helpful.
當(dāng)我在 GDB 中運(yùn)行我的應(yīng)用程序時(shí),它會在每次線程暫停或恢復(fù)時(shí)暫停.我希望我的應(yīng)用程序繼續(xù)正常運(yùn)行,直到其中一個(gè)線程因該異常而死亡,此時(shí)一切都應(yīng)該停止,以便我可以獲得回溯.
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.
推薦答案
您可以嘗試使用捕獲點(diǎn)"(catch throw
)在生成異常的點(diǎn)停止調(diào)試器.
You can try using a "catchpoint" (catch throw
) to stop the debugger at the point where the exception is generated.
以下 摘錄 來自 gdb 手冊描述了捕獲點(diǎn)功能.
The following excerpt From the gdb manual describes the catchpoint feature.
5.1.3 設(shè)置捕捉點(diǎn)
5.1.3 Setting catchpoints
您可以使用捕獲點(diǎn)使調(diào)試器因某些類型的程序事件而停止,例如 C++ 異常或共享庫的加載.使用 catch 命令設(shè)置捕獲點(diǎn).
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.
捕捉事件
在事件發(fā)生時(shí)停止.事件可以是以下任何一種:
Stop when event occurs. event can be any of the following:
扔
throw
拋出 C++ 異常.
抓住
catch
捕獲 C++ 異常.
執(zhí)行
exec
對 exec 的調(diào)用.目前僅適用于 HP-UX.
A call to exec. This is currently only available for HP-UX.
叉
fork
調(diào)用 fork.目前僅適用于 HP-UX.
A call to fork. This is currently only available for HP-UX.
vfork
vfork
調(diào)用 vfork.目前僅適用于 HP-UX.
A call to vfork. This is currently only available for HP-UX.
加載或加載庫名
任何共享庫的動態(tài)加載,或者庫libname的加載.目前僅適用于 HP-UX.
The dynamic loading of any shared library, or the loading of the library libname. This is currently only available for HP-UX.
卸載或卸載libname
卸載任何動態(tài)加載的共享庫,或卸載庫 libname.這目前僅適用于 HP-UX.
The unloading of any dynamically loaded shared library, or the unloading of the library libname. This is currently only available for HP-UX.
tcatch 事件
設(shè)置一個(gè)只啟用一站的捕獲點(diǎn).第一次捕獲事件后,捕獲點(diǎn)會自動刪除.
Set a catchpoint that is enabled only for one stop. The catchpoint is automatically deleted after the first time the event is caught.
如果您以交互方式調(diào)用函數(shù),GDB 通常會在函數(shù)執(zhí)行完畢后將控制權(quán)返回給您.但是,如果調(diào)用引發(fā)異常,則調(diào)用可能會繞過將控制權(quán)返回給您的機(jī)制,并導(dǎo)致您的程序中止或繼續(xù)運(yùn)行,直到遇到斷點(diǎn)、捕獲 GDB 正在偵聽的信號或退出.即使您為異常設(shè)置了捕獲點(diǎn),情況也是如此;在交互式調(diào)用中禁用異常捕獲點(diǎn).
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.
使用 info break
命令列出當(dāng)前的捕獲點(diǎn).
Use the info break
command to list the current catchpoints.
目前在 GDB 中對 C++ 異常處理(catch throw 和 catch catch)有一些限制:
There are currently some limitations to C++ exception handling (catch throw and catch catch) in GDB:
您不能以交互方式引發(fā)異常.
You cannot raise an exception interactively.
您不能以交互方式安裝異常處理程序.
You cannot install an exception handler interactively.
有時(shí) catch 不是調(diào)試異常處理的最佳方式:如果您需要確切地知道異常在哪里引發(fā),最好在調(diào)用異常處理程序之前停止,因?yàn)檫@樣您可以在任何展開之前看到堆棧發(fā)生.如果您改為在異常處理程序中設(shè)置斷點(diǎn),則可能不容易找出引發(fā)異常的位置.
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.
要在調(diào)用異常處理程序之前停止,您需要了解一些實(shí)現(xiàn)知識.在 GNU C++ 的情況下,異常是通過調(diào)用名為 __raise_exception 的庫函數(shù)引發(fā)的,該函數(shù)具有以下 ANSI C 接口:
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);
要使調(diào)試器在任何堆棧展開之前捕獲所有異常,請?jiān)?__raise_exception 上設(shè)置斷點(diǎn)(請參閱斷點(diǎn);觀察點(diǎn);和異常部分).
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).
使用取決于 id 值的條件斷點(diǎn)(參見中斷條件部分),您可以在引發(fā)特定異常時(shí)停止程序.當(dāng)引發(fā)多個(gè)異常中的任何一個(gè)時(shí),您可以使用多個(gè)條件斷點(diǎn)來停止您的程序.
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.
這篇關(guān)于在 GDB 中運(yùn)行應(yīng)用程序直到發(fā)生異常的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!