8 Stimmen

Finde das Objekt, das std::out_of_range wirft

Ein Programm von mir wirft eine std::out_of_range. Ich kenne den Grund dafür, ich greife irgendwo auf einen Vektor mit dem Index -1 zu. Was ich nicht weiß, ist der Name des Vektors (Variablenname) und die Position im Code. Die Fehlermeldung, die mein Programm produziert, sieht folgendermaßen aus:

terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
zsh: abort (core dumped)  ./main.x config.cfg  

während die Fehlermeldung, die vom Code eines anderen Benutzers (der auch g++ verwendet) produziert und in der Frage C++ accessing vector veröffentlicht wurde, folgendermaßen aussieht:

Error for vec.at(i).setVec(tmp);
Error is:  terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check  

Er wird also über den Namen der Variablen informiert. Meine Frage ist:

Gibt es eine Möglichkeit, g++/gcc zu sagen, mir die erweiterten Informationen zu geben? Vielleicht sogar einschließlich der Zeilennummern (keine Ahnung, ob das möglich ist, aber hey, ein Mann kann träumen ;) ).
Nur zum Spaß habe ich mein Programm in gdb mit der Option catch thrown gestartet (ich muss hinzufügen, dass ich nahezu keine Erfahrung im Umgang mit einem echten Debugger habe), was mir auch nichts Neues gesagt hat, tatsächlich hat es mir nicht gesagt, dass der Fehler aufgrund einer std::out_of_range-Ausnahme aufgetreten ist.

Übrigens, meine Compiler-Flags (für Debugging) sind:

CFLAGS = --exceptions -I$(ROOTSYS)/include --std=c++11 -Wall -g -O0 -fno-inline -fno-eliminate-unused-debug-types

4voto

MSalters Punkte 166675

Setzen Sie einen Breakpoint auf std::out_of_range::out_of_range. Ein Ausnahmeobjekt, wie alle C++-Objekte, beginnt sein Leben nachdem sein Konstruktor beendet ist.

[EDIT] Der Kommentar hat es klargestellt: das Problem ist der von std::out_of_range::what() erzeugte String. Das ist implementationsdefiniert. Offensichtlich wird er in Ihrem Fall aus __FUNCTION__ zusammengesetzt, einem GCC-Makro, das den aktuellen (d.h. werfenden) Funktionennamen angibt. Aber eine solche Funktion kennt nur this, d.h. den Zeiger auf das aktuelle Objekt und nicht dessen Namen. In einem anderen Fall wird der Objektname über eine andere Methode als std::out_of_range::what() abgerufen.

4voto

Basilevs Punkte 20145

Nachdem Sie den Breakpoint erreicht haben, geben Sie den Befehl bt (Backtrace) in der gdb-Shell ein. Dies druckt den Stack-Trace (eine Sequenz von Funktionsaufrufen, die zum Fehler führen).

Um den Variablennamen zu erhalten, können Sie nun den Befehl up verwenden, um im Stack nach oben zu navigieren und zu sehen, welche Variablen in jeder dieser Funktionen verwendet wurden.

1voto

luca Punkte 6038

Um bei jeder geworfenen Ausnahme einen Haltepunkt zu vermeiden und nur bei std::out_of_range anzuhalten, verwenden Sie diesen Befehl in gdb:

catch throw std::out_of_range

Führen Sie dann den Befehl bt oder where aus, wenn der Haltepunkt erreicht wird, um zu sehen, wo im Code die Ausnahme ausgelöst wurde

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X