8

Wie kommst du normalerweise um dieses Problem? Stellen Sie sich vor, ein Thread stürzt innerhalb von libc-Code (der eine gemeinsam genutzte Systembibliothek ist) auf Computer1 ab und erzeugt dann einen Arbeitsspeicherabzug. Aber der Computer2, auf dem dieser Arbeitsspeicherabzug analysiert wird, könnte eine andere Version von libc haben.Remote-Post-Mortem-Coredump-Analyse ohne genaue Debug-Symbole für gemeinsame Systembibliotheken

So:

  1. Wie wichtig es ist das gleiche gemeinsam genutzte Bibliothek auf dem Remote-Computer zu haben ist? Wird die gdb Stacktrace korrekt rekonstruieren, ohne genau dieselbe Version von libc auf Conputer2 zu haben?

  2. Wie wichtig ist es, korrekte Debug-Symbole für libc zu haben? Wird die gdb Stacktrace korrekt rekonstruieren, ohne exakt dieselben Debug-Symbole auf dem Computer2 zu haben?

  3. Und was ist die "richtige" Möglichkeit, dieses Debug-Symbol-Mismatch-Problem für gemeinsam genutzte Systembibliotheken zu vermeiden? Für mich scheint es, dass es keine einzige Lösung gibt, die dieses Problem elegant löst. Vielleicht kann jemand seine Erfahrung teilen?

Antwort

14
  1. Es hängt davon ab. Bei einigen Prozessoren, wie z. B. x86_64, sind die korrekten unwind descriptors Daten erforderlich, damit GDB den Stapel ordnungsgemäß abwickeln kann. Auf einer solchen Maschine wird das Analysieren von Coredump mit nicht übereinstimmender libc wahrscheinlich vollständigen Müll erzeugen.

  2. Sie benötigen keine Debug-Symbole für libc, um die Stack-Trace zu erhalten. Sie würden keine Datei- und Zeilennummern ohne Debug-Symbole erhalten, aber Sie sollten korrekte Funktionsnamen erhalten (außer wenn Inlining stattgefunden hat).

  3. Die Prämisse Ihrer Frage ist falsch - Debug-Symbole haben damit nichts zu tun. Die „richtige“ Art und Weise auf C2 zu analysieren coredump, wenn das coredump auf C1 hergestellt wurde, ist eine Kopie von C1 Bibliotheken haben (in zB /tmp/C1/lib/...) und direkten GDB diese Kopie zu verwenden, anstatt die libc mit

    der C2 installiert

    (gdb) set solib-absolute-prefix /tmp/C1

Befehl.

Hinweis: Obige Einstellung muss wirksam sein, bevor Sie den Kern in GDB laden. Dieser:

wird nicht funktionieren (Core wird gelesen, bevor die Einstellung in Kraft ist). Hier

ist der richtige Weg:

gdb exe 
(gdb) set solib-absolute-prefix /tmp/C1 
(gdb) core core 

(Ich habe versucht, einen Verweis auf den im Internet zu finden, aber nicht).

Was sind Abwicklungsdeskriptoren?

Unwind-Deskriptoren sind erforderlich, wenn Code ohne Rahmenzeiger kompiliert wird (Standard für x86_64 im optimierten Modus).Ein solcher Code tut nicht speichern% rbp registrieren, und so GDB muss gesagt werden, wie "zurück" aus dem aktuellen Frame auf den Aufrufer-Frame (dieser Prozess ist auch bekannt als Stack Abwickeln).

Warum ist C1's libc.so nicht im Kern enthalten?

Die Core-Datei enthält normalerweise nur Inhalte beschreibbarer Segmente des Programmadressraums. Die schreibgeschützten Segmente (in denen sich ausführbarer Code und Abwicklungsdeskriptoren befinden) sind normalerweise nicht erforderlich - Sie können sie direkt von libc.so auf der Festplatte lesen.

Außer das funktioniert nicht, wenn Sie C1's Kern auf C2 analysieren!

Einige (aber nicht alle) Betriebssysteme erlauben es, "Full Coredumps" zu konfigurieren, bei denen das Betriebssystem auch schreibgeschützte Mappings abspeichert, so dass Sie den Core auf jedem Rechner analysieren können.

+0

1. Könnten Sie bitte den Begriff "korrekte Abwicklungsdeskriptoren" erklären - beziehen Sie sich auf SP- und BP-Register, die im Stapel geschoben wurden? 2. Wenn Coredump generiert wird alle Shared Libraries sind auch in Coredump enthalten, weil es im Grunde Speicherauszug ist? Also, warum GDB libc.so Datei haben muss, während es die libc von coredump verwenden kann? –

+0

Ich habe Ihre zusätzlichen Fragen beantwortet (so gut ich konnte). –

+0

Danke - die Antworten waren ausgezeichnet! Ich bin immer noch neugierig, wo ich weitere Informationen darüber finden kann, "wie Abwicklungsdeskriptoren funktionieren" ... –

Verwandte Themen