2009-07-12 22 views
89

Ich arbeite an einer Multithread-Anwendung, und ich möchte es mit GDB debuggen.Eine Anwendung in GDB ausführen, bis eine Ausnahme auftritt

Problem ist, einer meiner Fäden hält mit der Nachricht zu sterben:

pure virtual method called 
terminate called without an active exception 
Abort 

ich die Ursache dieser Nachricht weiß, aber ich habe keine Ahnung, wo in meinem Thread es auftritt. Ein Backtrace wäre wirklich hilfreich.

Wenn ich meine App in GDB ausführen, wird jedes Mal angehalten, wenn ein Thread ausgesetzt oder fortgesetzt wird. Ich möchte, dass meine App normal weiterläuft, bis einer der Threads mit dieser Ausnahme abstirbt. An diesem Punkt sollte alles anhalten, damit ich ein Backtrace erhalten kann.

+0

Welches Signal meldet die GDB, wenn sie pausiert? Sie sollten in der Lage sein, einen Befehl wie 'handle SIGUSR1 pass noprint nostop' – Hasturkun

Antwort

126

Sie können versuchen, eine „Catchpoint“ (catch throw) mit dem Debugger an dem Punkt zu stoppen, wo die Ausnahme erzeugt wird.

Die folgenden excerpt Aus dem Gdb-Handbuch beschreibt die Catchpoint-Funktion.


5.1.3 Einstellung Schutzweiche

Sie Schutzweiche verwenden können, um zu bewirken, das Debugger für bestimmte Arten von Programmereignissen zu stoppen, wie C++ Ausnahmen oder das Laden einer gemeinsam genutzten Bibliothek. Verwenden Sie den Fangbefehl, um einen Fangpunkt festzulegen.

  • Fang Ereignis

    Stop, wenn Ereignis auftritt. Ereignis kann eine der folgenden sein:

    • Wurf

      Das Werfen einer C++ Ausnahme.

    • catch

      Das Einfangen eines C++ Ausnahme.

    • exec

      Ein Aufruf von exec. Dies ist derzeit nur für HP-UX verfügbar.

    • Gabel

      Ein Anruf Gabel. Dies ist derzeit nur für HP-UX verfügbar.

    • vfork

      Ein Aufruf vfork. Dies ist derzeit nur für HP-UX verfügbar.

    • Last oder Last libname

      Die dynamische Laden von jeder gemeinsam benutzte Bibliothek oder das Laden der Bibliothek libname. Dies ist derzeit nur für HP-UX verfügbar.

    • unload oder unload libname

      Das Entladen jeder dynamisch gemeinsam genutzten Bibliothek geladen wird, oder das Entladen der Bibliothek libname. Dies ist derzeit nur für HP-UX verfügbar.

  • tcatch Ereignis

    ein Catchpoint Set, das für nur eine Station aktiviert ist. Der Catchpoint wird automatisch nach dem ersten Auffinden des Ereignisses gelöscht.

Verwenden Sie den Befehl info break die aktuellen Schutzweiche aufzulisten.

Es liegen noch einige Einschränkungen C++ Ausnahmebehandlung (catch throw und Beifang) 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. 

Manchmal fangen ist nicht der beste Weg, die Handhabung zu Debug-Ausnahme: Wenn Sie genau wissen müssen, wo ein Wenn die Exception ausgelöst wird, ist es besser anzuhalten, bevor der Exception-Handler aufgerufen wird, da Sie auf diese Weise den Stack sehen können, bevor ein Unwinding stattfindet. Wenn Sie stattdessen einen Haltepunkt in einem Ausnahmebehandler festlegen, ist es möglicherweise nicht einfach herauszufinden, wo die Ausnahme ausgelöst wurde.

Um kurz vor dem Aufruf eines Exception-Handlers zu stoppen, benötigen Sie Kenntnisse über die Implementierung. Im Falle der GNU C++, sind Ausnahmen durch den Aufruf einer Bibliotheksfunktion namens __raise_exception angehoben, die die folgenden ANSI-C-Schnittstelle:

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

Um den Debugger fangen alle Ausnahmen zu machen, bevor ein Stapel Abwickeln stattfindet, einen Haltepunkt setzen auf __raise_exception (siehe Abschnitt Breakpoints; Watchpoints und Ausnahmen).

Mit einem bedingten Breakpoint (siehe Abschnitt Break-Bedingungen), der vom Wert von id abhängt, können Sie Ihr Programm stoppen, wenn eine bestimmte Ausnahme ausgelöst wird. Sie können mehrere bedingte Haltepunkte verwenden, um Ihr Programm zu stoppen, wenn eine Anzahl von Ausnahmen ausgelöst wird.

+0

Bitte haben Sie die 100. Upvote. – YSC

5

ein Haltepunkt auf __pure_virtual

+0

In @ JeffreyHill Antwort, es heißt jetzt __cxa_pure_virtual. Ich weiß nicht, wie ich das selbst überprüfen soll, deshalb möchte ich die Antwort nicht bearbeiten. Ich habe nicht vor zu stimmen, aber die Antwort könnte jetzt falsch sein und sollte von jemandem bearbeitet werden, der weiß, was richtig ist. –

3

FWIW, offenbar wurde in gcc 4.1 der entsprechende Funktionsname geändert und in dieser Funktion muss ein Haltepunkt gesetzt werden.

__cxa_pure_virtual

Verwandte Themen