Wie die Spitze eines Stapelüberlauf zu erfassen,
-
09-09-2019 - |
Frage
Ich habe folgendes Problem mit meinem C-Programm: Irgendwo ist ein Stapelüberlauf. Trotz ohne Optimierung kompiliert und mit Debugger Symbolen, verläßt das Programm mit diesem Ausgang (innerhalb oder außerhalb von GDB auf Linux):
Programm beendet mit Signal SIGSEGV, Fehlersegmentierung. Das Programm ist nicht mehr vorhanden.
Die einzige Art, wie ich, dass dies tatsächlich erkennen könnte, ist Stack-Überlauf wurde das Programm durch valgrind läuft. Gibt es eine Weise, die ich irgendwie das Betriebssystem zwingen kann, ein Call-Stack-Trace-Dump, die mir das Problem lokalisieren würde helfen?
Leider ist gdb mir nicht erlauben, einfach entweder in das Programm zu erschließen.
Lösung
Wenn Sie das System erlauben Core-Dateien zu entleeren Sie sie mit GDB analysieren können:
$ ulimit -c unlimited # bash sentence to allow for infinite sized cores
$ ./stack_overflow
Segmentation fault (core dumped)
$ gdb -c core stack_overflow
gdb> bt
#0 0x0000000000400570 in f ()
#1 0x0000000000400570 in f ()
#2 0x0000000000400570 in f ()
...
Einige Male habe ich eine schlecht erzeugte Core-Datei gesehen haben, die eine falsche Stack-Trace hatte, aber in den meisten Fällen die bt wird ein Bündel von rekursiven Aufrufen der gleichen Methode ergeben.
Die Core-Datei möglicherweise einen anderen Namen hat, der den Prozess-ID enthalten könnte, ist es auf der Standard-Konfiguration des Kernels in Ihrem aktuellen System hängt, kann aber mit (als root ausführen oder mit sudo) gesteuert werden:
$ sysctl kernel.core_uses_pid=1
Andere Tipps
Mit GCC können Sie dies versuchen:
-fstack-protector
Emit zusätzlichen Code für Pufferüberlauf zu überprüfen, wie Stack Smashing-Angriffe. Dies wird durch das Hinzufügen einer Wache Variable Funktionen mit empfindlichen Objekten gemacht. Dies umfasst Funktionen, die alloca nennen, und Funktionen mit Puffern größer als 8 Bytes. Die Wachen werden initialisiert, wenn eine Funktion eingegeben und dann überprüft, wenn die Funktion beendet. Wenn eine Schutzprüfung fehlschlägt, wird eine Fehlermeldung ausgegeben und das Programm beendet wird.
-fstack-protector-all
Wie -fstack-Schutz außer, dass alle Funktionen geschützt sind.
http: // gcc. gnu.org/onlinedocs/gcc-4.3.3/gcc/Optimize-Options.html#Optimize-Options
Wenn ein Programm mit SIGSEGV stirbt, ist es normalerweise Dumps Kern auf Unix. Könnten Sie diesen Kern in Debugger laden und den Zustand des Stapels überprüfen?