GDB beschädigter Stack-Frame - Wie Debuggen?
Habe ich folgenden stack trace. Ist es möglich, alles, was nützlich für das Debuggen?
Program received signal SIGSEGV, Segmentation fault.
0x00000002 in ?? ()
(gdb) bt
#0 0x00000002 in ?? ()
#1 0x00000001 in ?? ()
#2 0xbffff284 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb)
Wo zu Beginn der Suche auf den code, wenn wir einen Segmentation fault
, und der stack-trace ist das nicht so sinnvoll?
HINWEIS: Wenn ich nach dem code, dann wird das, SO Experten, wird mir die Antwort geben. Ich möchte die Anleitung von SO und finde die Antwort selbst, also bin ich nicht posten den code hier. Entschuldigung.
Kommentar zu dem Problem
Wahrscheinlich ist dein Programm sprang in die Unkraut - können Sie sich erholen, die nichts von der stack-pointer?
Eine andere Sache zu prüfen ist, wenn der Rahmen-Zeiger richtig eingestellt ist. Bauen Sie ohne Optimierungen oder der übergabe der fahne wie
-fno-omit-frame-pointer
? Auch für die Speicher-Korruption, valgrind
möglicherweise eine besser geeignete tool, wenn es eine option für Sie. InformationsquelleAutor der Frage Sangeeth Saravanaraj | 2012-03-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Jener falschen Adressen (0x00000002) sind eigentlich PC-Werte, nicht SP-Werte. Nun, wenn Sie erhalten diese Art von SEGV, mit einem Schein (sehr kleinen) PC-Adresse, 99% der Zeit ist es aufgrund Berufung durch eine Schein-Funktion Zeiger. Beachten Sie, dass virtuelle Aufrufe in C++ implementiert sind, die über Funktionszeiger, so dass jedes problem mit einem virtuellen call kann sich manifestieren in der gleichen Weise.
Einen indirekten Aufruf-Anweisung nur schiebt der PC nach dem Aufruf auf dem stack und legt dann den PC mit der Ziel-Wert (Schein-in diesem Fall), wenn dieser ist, was passiert ist, können Sie leicht rückgängig machen, indem Sie manuell knallen Sie den PC aus dem stack. In 32-bit-x86-code, den Sie nur:
Mit 64-bit-x86-code, den Sie benötigen
Dann, Sie sollten in der Lage sein zu tun, ein
bt
und herauszufinden, wo der code wirklich ist.Den anderen 1% der Zeit, wird der Fehler durch überschreiben des stack, in der Regel durch überlaufen eines Arrays auf dem stack gespeichert werden. In diesem Fall könnten Sie in der Lage sein, mehr Klarheit über die situation, indem Sie mit einem tool wie valgrind
InformationsquelleAutor der Antwort Chris Dodd
Wenn die situation ist ziemlich einfach, Chris Dodd ' s Antwort ist die beste. Es sieht aus wie es sprang durch einen NULL-Zeiger.
Es ist jedoch möglich, das Programm schoss sich in den Fuß -, Knie -, Hals-und Augen-vor dem Absturz—überschrieben den stack Durcheinander der frame-pointer, und andere übel. Wenn dem so ist, dann entwirren der hash ist nicht wahrscheinlich, Ihnen zu zeigen, Kartoffeln und Fleisch.
Die effizientere Lösung sein wird, um führen Sie das Programm im debugger, und Schritt über die Funktionen, bis das Programm abstürzt. Einmal Absturz-Funktion identifiziert wird, starten Sie erneut und Schritt in die Funktion und bestimmen, welche Funktion es fordert zum Absturz. Wiederholen Sie, bis Sie die einzige problematische Codezeile. 75% der Zeit, das Update wird dann offensichtlich sein.
In den anderen 25% der Situationen, die so genannte problematische Codezeile ist ein Roter Hering. Es wird zu reagieren (ungültig) Bedingungen viele Zeilen vor—vielleicht Tausende von Zeilen vor. Wenn das der Fall ist, natürlich am besten gewählt wird, hängt von vielen Faktoren ab: vor allem Ihr Verständnis von code und Erfahrungen mit:
printf
's auf der kritischen Variablen wird dazu führen, dass notwendige ha!Glück!
InformationsquelleAutor der Antwort wallyk
Unter der Annahme, dass der stack-pointer ist gültig...
Kann es unmöglich sein, genau zu wissen, wo die SEGV tritt aus der backtrace-ich denke, die ersten zwei stack frames werden komplett überschrieben. 0xbffff284 scheint wie eine gültige Adresse, aber die nächsten beiden nicht. Für einen genaueren Blick auf den Stapel, können Sie Folgendes versuchen:
gdb$ x/32ga $rsp
oder eine Variante (ersetzen Sie die 32 mit einer anderen Nummer). , Drucken Sie einige Anzahl der Wörter (32) ausgehend von der stack-pointer des Riesen (g) Größe, formatiert wie Adressen (a). Geben Sie 'help x' für mehr info auf format.
Instrumentierung Ihren code mit einigen sentinel 'printf"s vielleicht gar keine schlechte Idee, in diesem Fall.
InformationsquelleAutor der Antwort manabear
Blick auf einige Ihrer anderen Register zu sehen, ob einer von Ihnen der stack-pointer Cache in Ihnen. Von dort aus, können Sie zum abrufen von einem Stapel. Auch, wenn dies eingebettet ist, oft Stapel definiert ist, an einer ganz besonderen Adresse. Mit, dass, können Sie auch manchmal einen anständigen stack. Dies alles setzt Voraus, dass, wenn Sie sprang auf den Hyperraum, Ihr Programm nicht kotzen alle über Speicher-auf dem Weg...
InformationsquelleAutor der Antwort Michael Dorgan
Wenn es ein stack überschreiben, können die Werte gut übereinstimmen, um etwas erkennbares aus dem Programm.
Zum Beispiel, fand ich mich Blick auf den Stapel
sowie
0x342d
ist, 13357, die sich als eine Knoten-id, wenn ich grep die Anwendung protokolliert. Dass sofort geholfen eingrenzen Kandidaten-Websites, auf denen der stack überschreiben, die möglicherweise aufgetreten sind.InformationsquelleAutor der Antwort Craig Ringer