2009-09-26 7 views
6

Ich habe eine Server-Anwendung unter Cent OS ausgeführt. Der Server antwortet viele Anfragen pro Sekunde, aber es stürzt wiederholt nach jeder Stunde ab und erstellt eine Absturzspeicherungsdatei. Die Situation ist wirklich schlecht und ich muss die Ursache des Absturzes so schnell wie möglich herausfinden.Wie eine Crash-Dump-Datei mit GDB zu analysieren

Ich vermute, dass das Problem ein Nebenläufigkeitsproblem ist, aber ich bin mir nicht sicher. Ich habe Zugriff auf die Quellcode- und Crash-Dump-Dateien, aber ich weiß nicht, wie man die Crash-Dumps benutzt, um das Problem zu lokalisieren.

Alle Vorschläge werden sehr geschätzt.

Antwort

7

Das erste, was zu suchen, ist die Fehlermeldung, die Sie, wenn Sie die Programmabstürze bekommen. Dies wird oft sagen, welche Art von Fehler aufgetreten ist. Zum Beispiel "segmentation fault" oder "SIGSEGV" bedeutet fast sicher, dass Ihr Programm einen NULL oder sonst ungültigen Zeiger de-referenziert hat. Wenn das Programm in C++ geschrieben wird, wird Ihnen die Fehlermeldung oft den Namen einer nicht abgefangenen Ausnahme mitteilen.

Wenn die Fehlermeldung nicht angezeigt wird, führen Sie das Programm über die Befehlszeile aus, oder leiten Sie die Ausgabe in eine Datei um.

Damit eine Kerndatei wirklich nützlich ist, müssen Sie Ihr Programm ohne Optimierung und mit Debuginformationen kompilieren. GCC benötigt die folgenden Optionen: -g -O0. (Stellen Sie sicher, dass Ihr Build keine anderen -O Optionen hat.

)

Sobald Sie die Core-Datei haben, öffnen Sie sie dann in gdb mit:

gdb YOUR-APP COREFILE 

Typ where den Punkt zu sehen, wo der Absturz aufgetreten. Sie befinden sich im Grunde genommen in einer normalen Debugging-Sitzung - Sie können Variablen untersuchen, den Stack auf und ab bewegen, zwischen Threads wechseln und was auch immer.

Wenn Ihr Programm abgestürzt ist, dann ist es wahrscheinlich ein ungültiger Speicherzugriff - Sie müssen also nach einem Zeiger suchen, der einen Nullwert hat oder auf schlecht aussehende Daten zeigt. Möglicherweise finden Sie das Problem nicht ganz am Ende des Stapels, Sie müssen möglicherweise den Stapel ein paar Stufen nach oben verschieben, bevor Sie das Problem finden.

Viel Glück!

0

Erstellt Ihre App eine Core-Datei? Wenn ja, würde ich gdb verwenden, um dieses Problem zu beheben.

9

Wenn das Problem eine Stunde oder so dauert, kann es sich um ein Speicherproblem handeln - z. B. beim Ablaufen oder möglicherweise beim Trampling (z. B. bei bereits freigegebenem Speicher).

Sie sagen, Sie haben die Crash-Dump-Dateien - das ist ein Core-Dump?

Vorausgesetzt, dass Sie einen Core Dump haben, dann ist der erste Schritt sollte wohl sein, den Stapel Backtrace drucken:

gdb program core 
> where 

Dies sollte Ihnen sagen, wo das Programm war, als der Absturz aufgetreten. Was noch verfügbar ist, hängt davon ab, wie der Server kompiliert wurde. Wenn möglich, sollten Sie das Debugging neu starten (das wäre mit dem Flag '-g' mit GCC). Dies würde Ihnen mehr Informationen aus dem Stack-Backtrace geben.

Wenn Ihr Problem speicherbezogen ist, sollten Sie mit valgrind arbeiten.

Beachten Sie auch das Erstellen und Ausführen mit einer Debugging-Version von malloc(). Eine Debugging-Version erkennt Speichermissbrauch, die normale Versionen vermissen - oder abstürzen.

+0

Danke für Ihre ausführliche Antwort. Der Server wurde mit Debugging-Informationen kompiliert und erstellt beim Absturz einen Core-Dump. Der Server initialisiert viele Threads. Immer wenn die Threads weniger als 200 sind, bleibt der Server länger als eine Stunde in Betrieb. Wenn jedoch die Anzahl der Threads im Pool auf 300 erhöht wird, stürzt der Server viel schneller ab. Können Sie mir bitte sagen, wie kann die Verwendung einer Debugging-Version von malloc helfen? Dank –

+0

In Bezug auf "Debugging malloc": Wenn das Problem Speichermissbrauch ist, hilft das Debugging malloc durch Aufnahme weiterer Informationen über den zugewiesenen Speicherplatz, in der Regel durch Zuweisen von mehr Speicherplatz, so wenn sie aufgerufen werden, können sie verschiedene Arten erkennen früherer Nutzung von Speichermissbrauch - Begrenzung des angerichteten Schadens und in der Regel leichteres Erkennen des Problems. Wenn Sie beispielsweise einen bereits freigegebenen Speicherbereich freigeben, kann er dies melden - anstatt nur Ihren freien Speicherplatz zu verwenden und mit den Informationen zu arbeiten, die nicht wirklich vorhanden sind. Eine einfache Implementierung von malloc() finden Sie in K & R. –

+0

In Bezug auf 'unter 200 Fäden OK; über 300 stürzt früher ab '; Haben Sie untersucht, ob der Server einen Pool fester Größe einer Ressource (vielleicht 200, vielleicht 256) zuweist und nicht ordnungsgemäß auf Erschöpfung dieser Ressource prüft? Es könnte sich um eine Reihe von Mutexen oder Semaphoren oder etwas anderes handeln, das einen Speichermissbrauch auslöst. Ist der Servercode, den Sie geschrieben haben? Sollten Sie versuchen, die Anzahl der Threads bei der Arbeit zu begrenzen? –

5
gdb -c core.file exename 
bt 

es Angenommen exename wurde mit Debugging-Symbolen aufgebaut (und all seine dynamische Abhängigkeiten im Weg sind), dass Sie eine Rückverfolgung bekommen. 'hoch' und 'runter' bewegt Sie im Stapel nach oben und unten und p varname kann verwendet werden, um Einheimische und Parameter zu untersuchen.

Sie könnten auch versuchen, es unter valgrind ausgeführt wird:

valgrind --tool=memcheck --leak-check=full exename