2009-07-12 33 views
89

我正在使用多線程應用程序,並且我想使用GDB進行調試。在GDB中運行應用程序直到發生異常

問題是,我的一個線程保持與消息垂死:

pure virtual method called 
terminate called without an active exception 
Abort 

我知道消息的原因,但我不知道在哪裏我的線程它發生。回溯會很有幫助。

當我在GDB中運行我的應用程序時,它會在每次線程暫停或恢復時暫停。我希望我的應用程序能夠繼續正常運行,直到其中一個線程死於此異常,此時一切都應停止,以便我可以回溯。

+0

GDB在暫停時報告什麼信號?你應該能夠運行一個類似`handle SIGUSR1 pass noprint nostop`的命令 – Hasturkun 2009-07-12 14:13:03

回答

126

您可以嘗試使用「捕獲點」(catch throw)斷點在產生異常的點停止調試器。

以下excerpt從gdb手冊介紹的catchpoint功能。


5.1.3設置捕獲

您可以使用捕獲點,以使調試器爲某些種類的程序事件,如C++異常或者是共享庫的加載。使用catch命令設置一個入口點。

  • 事件時事件發生

    停止。事件可以是任何以下的:

    • C++異常的投擲。

    • 捕獲

      C++異常的醒目。

    • EXEC

      調用exec。目前這僅適用於HP-UX。

    • 的呼叫到叉。目前這僅適用於HP-UX。

    • 的vfork

      調用對vfork。目前這僅適用於HP-UX。

    • 負載負載LIBNAME

      任何共享庫的動態加載,或圖書館LIBNAME的加載。目前這僅適用於HP-UX。

    • 卸載卸載LIBNAME

      任何動態加載共享庫的卸載,或庫libname卸載。目前這僅適用於HP-UX。

  • tcatch事件

    組僅一個站啓用捕獲點。在第一次捕捉到事件後,將自動刪除該匯點。

使用info break命令列出目前的捕獲。

目前對C++異常一定的侷限性處理(捕捉拋出和捕獲捕獲)在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. 

有時候,美中不足的是沒有調試異常處理的最佳方式:如果你需要知道確切位置的引發異常,最好在調用異常處理程序之前停止,因爲這樣可以在任何展開之前看到堆棧。如果您在異常處理程序中設置斷點,則可能不容易找出引發異常的位置。

要在調用異常處理程序之前停止,需要一些實現知識。

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

要讓調試器捕獲所有異常任何堆棧展開發生之前,上設置斷點:在GNU C++的情況下,異常是調用庫函數命名__raise_exception它具有以下ANSI C接口上調__raise_exception(請參閱斷點;觀察點和例外部分)。

使用依賴於id值的條件斷點(請參見斷點條件部分),可以在發生特定異常時停止程序。當引發多個異常時,您可以使用多個條件斷點來停止程序。

+0

請獲得第100個積分。 – YSC 2017-03-21 14:45:24

5

坐落在__pure_virtual

+0

在@JeffreyHill的答案中,現在叫做__cxa_pure_virtual。我不知道如何檢查自己,所以我不想編輯答案。我不打算投降,但現在的答案可能是錯誤的,應該由知道什麼是正確的人編輯。 – 2016-08-31 22:42:01

3

FWIW,顯然,在gcc 4.1中,相應的函數名稱已經更改,並且必須在此函數中設置斷點。

__cxa_pure_virtual

相關問題