Einleitung
Manchmal hat man sich die neueste must-have Applikation gemerged und beim Starten desselbigen "kackt" das Teil furchtbar weg.
Googeln, Bohren der Forums-Kollegen, bugzilla-grasen, USE-Flags Ratespiel, CFLAGS-switching ... nichts führt zum Ziel. Die Applikation will einfach nicht auf deiner Maschine. Aus. Das Teil schmiert einfach ab und weg.
Ein mögl. Ausweg, dem Fehlverhalten auf die Schliche zu kommen ist die Analyse von core dumps.
Was sind core dumps?
Ein core dump ist eine Datei, ein File, welches der Kernel im aktuellen laufenden Verzeichnis hinterlegt im Fall das eine Applikation sich nicht ordnungsgemäß beendet.
In einem core dump sind allerlei Sachen verzeichnet: stacktrace, symbole, memory, etc. etc.
Gibt man nun ein executable an und das zugehörige core file, dann kann man in einem Debugger ziemlich genau feststellen, warum der Kernel eine Applikation ziemlich unsanft aus dem Speicher geschossen hat.
Werden immer core dumps erstellt?
NEIN. Warum?
Ganz einfach: zunächst sind core dumps in der Regel recht groß. Hat man eine Applikation, welche regelmäßig abschmiert, müllt man sich zeimlich schnell diePlatte voll.
Zweitens befindet sich in einem core dump auch der Memory-Auszug des getöteten Prozesses und der kann sensible Informationen beinhalten, wie Passwörter, TANs, etc. Man braucht dann kein Informatik-Studium dazu um diese Informationen aus einem core dump file herauszuholen.
Ok. Wie komme ich nun zu einem core dump file?
Grundsätzlich guckt man mal, ob die Prozessumgebung das überhaupt zuläßt. Dazu klopft man mal
|
Quellcode
|
1
|
$ man core
|
ein und checkt, ob die Randbedingungen erfüllt sind.
Dazu zählen:
- Der Prozess muß Schreibrechte im aktuellen Verzeichnis haben
- Es muß genug Platz auf der Platte sein
- Der Prozess darf nicht das setuid haben (ok, da gibt es noch einige Kniffe dazu ... lesen!)
- ...
Wenn all dies erfüllt ist, gibt es noch eine "magische" Randbedingung: das ulimit für core dumps darf nicht 0 sein. ulimit legt die oberen Grenzen für (File-)Operationen fest.
|
Quellcode
|
1
2
|
$ ulimit -c
0
|
besagt, das keine core dumps erstellt werden, auch dann, wenn die Bedingungen in "man core" erfüllt sind.
|
Quellcode
|
1
|
$ ulimit -c unlimited
|
erstellt core dumps beliebiger Größe.
Was brauche ich noch zur Analyse?
Zunächst mal ist klarzustellen, das selten Executables Symbol-Informationen beinhalten und nicht darauf ausgelegt sind, je debuged zu werden.
Um das zu erreichen, ist mal das Studium von
http://www.gentoo.org/proj/en/qa/backtraces.xml zu empfehlen.
Dann empfehle ich hier mal dieses Setting:
|
Quellcode
|
1
|
# FEATURES+="nostrip" USE+="debug" emerge <application-which-crashes>
|
Außerdem dreht die CFLAGS Optimierungen ab. Kein "-O2", -"O3" oder sowas. Diese Optimierungen stellen eine Menge mit dem Erzeugten Code an, welche die Analyse sehr erschweren.
Im Einzelnen:
- FEATURES+="nostrip": das verhindert, das Symbolinformation aus den Executables und Libraries entfernt wird. Für das Ausführen der Programme sind diese nicht notwendig und das Entfernen derselben spart Platz. ABER: Analyse-Werkzeuge (wie bsp. "nm") tun sich dann sehr schwer ... und manchmal verunmöglicht das deren Einsatz überhaupt.
- USE+="debug": bringt den gcc dazu, noch zusätzliche Debug-Informationen ("-ggdb") reinzukompilieren.
... und?
Yep! Noch ein Tip. Standardmäßig wird einfach das File "core" angelegt. Das ist an sich ok, aber manchmal etwas irrig, wenn nämlich App "xyz" ausgeführt wird, welche aber App "abc" zum crashen bringt ...
Damit der core dump Filename noch etwas ausführlicher wird, kann man den Kernel mitgeben, wie man es möchte:
|
Quellcode
|
1
|
# echo "core.%e.%p" > /proc/sys/kernel/core_pattern
|
legt core files an, welche den Namen der gecrashten Application beinhalten, sowie deren PID.
Jetzt habe ich ein core file! Hurra! Bloß, ... wat nu?
Analysieren! Man holt sich den gdb, bzw. wenn man es grafisch haben möchte, den kdbg, lädt das gecrashte Executable und das core file ... und ab!
Dazu ist es unumgänglich, das man etwas von C/C++ versteht sowie die - zugegeben mögl. etwas "hantige" - Benutzung der Tools versteht.
Ein etwas halbwegs erfahrener Progie kann jedenfalls mit diesen Teilen sehr exakt feststellen, was die App zum crashen gebracht hat und *damit* wird eine Lösung des Problems schon wesentlich klarer.