Was passiert, wenn eine Kerndatei von einer anderen Linux-Distribution als der, die wir in Dev ausführen, generiert wird? Ist der Stacktrace überhaupt aussagekräftig?
Wenn die ausführbare Datei dynamisch gelinkt ist, wie es bei Ihnen der Fall ist, wird der Stack, den GDB erzeugt, (höchstwahrscheinlich) nicht aussagekräftig sein.
Der Grund:GDB weiß, dass Ihre ausführbare Datei abgestürzt ist, indem sie etwas in libc.so.6
aufgerufen hat unter der Adresse 0x00454ff1
, aber es weiß nicht, welcher Code an dieser Adresse war. Es schaut also in Ihre Kopie von libc.so.6
und entdeckt, dass dies in select
ist , also gibt es das aus.
Aber die Chancen, dass 0x00454ff1
ist auch in Ihren Kunden ausgewählt Kopie von libc.so.6
sind recht klein. Höchstwahrscheinlich hatte der Kunde ein anderes Verfahren an dieser Adresse, vielleicht abort
.
Sie können disas select
verwenden , und beobachten Sie diesen 0x00454ff1
entweder mitten in einer Anweisung ist oder dass die vorherige Anweisung kein CALL
ist . Wenn einer dieser beiden zutrifft, ist Ihr Stack-Trace bedeutungslos.
Sie können aber helfen Sie sich selbst:Sie müssen sich nur eine Kopie aller Bibliotheken besorgen, die in (gdb) info shared
aufgelistet sind aus dem Kundensystem. Lassen Sie den Kunden sie z. B. mit
cd /
tar cvzf to-you.tar.gz lib/libc.so.6 lib/ld-linux.so.2 ...
Dann auf Ihrem System:
mkdir /tmp/from-customer
tar xzf to-you.tar.gz -C /tmp/from-customer
gdb /path/to/binary
(gdb) set solib-absolute-prefix /tmp/from-customer
(gdb) core core # Note: very important to set solib-... before loading core
(gdb) where # Get meaningful stack trace!
Wir raten dem Kunden dann, eine -g-Binärdatei auszuführen, damit es einfacher zu debuggen ist.
viel besserer Ansatz ist:
- Erstellen mit
-g -O2 -o myexe.dbg
strip -g myexe.dbg -o myexe
- Verteilen Sie
myexe
an Kunden - wenn ein Kunde einen
core
erhält , verwenden Siemyexe.dbg
um es zu debuggen
Sie haben vollständige symbolische Informationen (Datei/Zeile, lokale Variablen), ohne dem Kunden eine spezielle Binärdatei schicken zu müssen und ohne zu viele Details über Ihre Quellen preiszugeben.
Sie können in der Tat nützliche Informationen aus einem Crash-Dump erhalten, sogar aus einer optimierten Kompilierung (obwohl es technisch gesehen "eine große Nervensäge" ist). a -g
Das Kompilieren ist in der Tat besser, und ja, Sie können dies sogar dann tun, wenn der Computer, auf dem der Speicherauszug stattfand, eine andere Distribution ist. Mit einer Einschränkung sind grundsätzlich alle wichtigen Informationen in der ausführbaren Datei enthalten und landen im Dump.
Wenn Sie die Kerndatei mit der ausführbaren Datei abgleichen, kann der Debugger Ihnen mitteilen, wo der Absturz aufgetreten ist, und Ihnen den Stapel anzeigen. Das allein sollte schon viel helfen. Sie sollten auch so viel wie möglich über die Situation herausfinden, in der es passiert – können sie es zuverlässig reproduzieren? Wenn ja, können Sie es reproduzieren?
Nun, hier ist der Vorbehalt:Der Ort, an dem die Vorstellung von „alles ist da“ zusammenbricht, ist bei gemeinsam genutzten Objektdateien, .so
Dateien. Wenn es aufgrund eines Problems mit diesen fehlschlägt, haben Sie nicht die Symboltabellen, die Sie benötigen. Sie können möglicherweise nur sehen, welche Bibliothek .so
es passiert in.
Es gibt eine Reihe von Büchern über das Debuggen, aber mir fällt keins ein, das ich empfehlen würde.