Verständnis GDB und Segfault-Meldungen

Ich war vor kurzem Debuggen einer Anwendung, die segfaulting auf einer regelmäßigen basis--habe ich das problem gelöst, das war relativ banal (Lesen von einem null-Zeiger), aber ich habe ein paar restliche Fragen, die ich habe nicht in der Lage zu lösen auf eigene Faust.

Dem gdb den stack-trace begann, wie dies in den meisten Fällen:

0x00007fdff330059f in __strlen_sse42 () from /lib64/libc.so.6

Mithilfe der Informationen aus /proc/[my proc id]/maps zu erreichen, die Basis-Adresse des shared-library, konnte ich sehen, dass das problem trat an der gleichen Anweisung der gemeinsam genutzten Bibliothek--auf Weisung 0x13259f, die

pcmpeqb (%rdi),%xmm1 (gdb)

So weit, So gut. Aber dann das OS (linux) würde auch schreiben, eine Fehlermeldung in /var/logs/messags, das sieht aus wie diese

[3540502.783205] node[24638]: segfault at 0 ip 00007f8abbe6459f sp 00007fff7bf2f148 error 4 in libc-2.12.so[7f8abbd32000+189000]

Was mich verwirrt. Auf der einen Seite, den kernel korrekt identifiziert den Fehler (ein-Benutzer-Modus Schutzverletzung), und durch die Subtraktion der base-Adresse des shared-library, aus der instruction-pointer, kommen wir an der gleichen relativen offset--0x13259f-wie wir es tun, durch gdb. Aber die Bibliothek, die der kernel erkennt ist anders, die Adresse des Befehls ist unterschiedlich, und die Funktion und Unterricht in der Bibliothek ist anders. Das heißt, die Anweisung in libc-2-12.so ist

0x13259f <__memset_sse2+911>:  movdqa %xmm0,-0x43(%edx)

So, meine Frage ist, wie kann gdb und die kernel-Meldung damit einverstanden, auf die Art der Störung und auf den offset der Anweisung relativ zu der Basis-Adresse des shared-library, aber nicht einverstanden auf die Adresse des instruction-pointer) und die shared-library verwendet?

Was Sie sehen, ist aufgrund der Tatsache, dass Prozess-privaten Adressen einen Einstieg in eine shared-library, die genau das sind. Lokal auf den Prozess. Sie wurden "verwandelt" vom kernel, von wo aus der text-segment, der die Bibliothek wirklich befindet. Um zu vergleichen, was Ihre Prozess erfordert. Die "nicht-transformierten" version ist kernel ansässig. Also, Sie sind beide richtig. Denken Sie über es. Alle Prozesse können eine 0x00000-Adresse (oder was auch immer Basis ist). Jeder Prozess' Basis-Adresse befindet sich physisch somnewhere sonst im realen Speicher. Nicht, wo der Prozess denkt, es ist.
Das macht Sinn, aber es erklärt nicht, warum der kernel sagte der Fehler ist aufgetreten in /lib/libc-2.12.so aber gdb setzen Sie den Fehler in der /lib64/libc.so.6. Ich bin mit einem 64-bit system, also vielleicht sind diese Bibliotheken sind die gleichen?
Ist ein symbolischer link, der andere ist die eigentliche library-Datei, die code verknüpft wurde, vor. Blick auf die Ausgabe von ldd-Befehl gegen die kompilierte Datei: ldd-myexecutable

InformationsquelleAutor Pseudo-Gorgias | 2013-06-03

Schreibe einen Kommentar