Wie kann man den Stack-Trace (vom Kernel oder Core-Dump) sinnvoll nutzen?

Lesezeit: 4 Minuten

Benutzer-Avatar
Shahbaz

Wenn Sie Glück haben, wenn Ihr Kernel-Modul abstürzt, erhalten Sie ein oops mit einem Protokoll mit vielen Informationen, wie Werten in den Registern usw. Eine solche Information ist der Stack-Trace (dasselbe gilt für Core-Dumps, aber ich hatte dies ursprünglich für Kernel-Module gefragt). Nehmen Sie dieses Beispiel:

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel]
[<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel]
[<c017d0e7>] ? __stop_machine+0x57/0x70
[<c016dec0>] ? __try_stop_module+0x0/0x30
[<c016f069>] ? sys_delete_module+0x149/0x210
[<c0102f24>] ? sysenter_do_call+0x12/0x16

Meine Vermutung ist, dass die +<number1>/<number2> hat etwas mit dem Offset von der Funktion zu tun, in der der Fehler aufgetreten ist. Das heißt, durch Überprüfen dieser Nummer, vielleicht durch Betrachten der Assembly-Ausgabe, sollte ich in der Lage sein, die Zeile (besser noch Anweisung) herauszufinden, in der dieser Fehler aufgetreten ist. Ist das korrekt?

Meine Frage ist, was sind diese beiden Zahlen genau? Wie nutzen Sie sie?

Benutzer-Avatar
Pavan Manjunath

skink_free_devices+0x32/0xb0

Dies bedeutet, dass die beleidigende Anweisung ist 0x32 Bytes ab Beginn der Funktion skink_free_devices() welches ist 0xB0 Bytes lang insgesamt.

Wenn Sie Ihren Kernel mit kompilieren -g aktiviert, dann können Sie die Zeilennummer innerhalb von Funktionen abrufen, bei denen die Steuerung mit dem Tool gesprungen ist addr2line oder unsere gute alte gdb

Etwas wie das

$ addr2line -e ./vmlinux 0xc01cf0d1
/mnt/linux-2.5.26/include/asm/bitops.h:244
or
$ gdb ./vmlinux
...
(gdb) l *0xc01cf0d1
0xc01cf0d1 is in read_chan (include/asm/bitops.h:244).
(...)
244     return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
(...)

Geben Sie also einfach die Adresse an, an der Sie die Inspektion durchführen möchten addr2line oder gdb und sie sollen Ihnen die Zeilennummer in der Quelldatei mitteilen, in der die anstößige Funktion vorhanden ist. Siehe Dies Artikel für alle Details

BEARBEITEN: vmlinux ist die unkomprimierte Version des Kernels, die zum Debuggen verwendet wird und im Allgemeinen @ gefunden wird /lib/modules/$(uname -r)/build/vmlinux vorausgesetzt, Sie haben Ihren Kernel aus Quellen gebaut. vmlinuz die Sie finden bei /boot ist der komprimierte Kernel und ist beim Debuggen möglicherweise nicht so nützlich

  • Ich wusste NICHT, dass Sie Linux selbst gdb können! Das ist fantastisch!

    – Shahbaz

    16. April 2012 um 12:13 Uhr

  • Wo ist vmlinux obwohl? Ich dachte, das wäre der Linux-Kernel selbst (in /boot), aber das ist es vmlinuz ... und addr2line sagt “Dateiformat nicht erkannt” Aber keine große Sache, da ich mich mehr für meine eigenen Module interessiere.

    – Shahbaz

    16. April 2012 um 12:15 Uhr

  • @Shahbaz vmlinuz ist nur die komprimierte und/oder gestrippte Version von vmlinux. BEIDE werden in der Regel im herumliegen /boot Mappe. Ich habe meine Linux-Box nicht dabei, um sie jetzt zu überprüfen. Googeln Sie nach den beiden 🙂 Hier sind einige Vorspeisen. Einer und Zwei

    – Pavan Manjunath

    16. April 2012 um 12:23 Uhr

  • @Shahbaz Schau hier nach vmlinux Datei /lib/modules/$(uname -r)/build/vmlinux vorausgesetzt, Sie haben Ihren Kernel aus Quellen auf derselben Maschine erstellt. Ansonsten siehe Dies posten, wie man den unkomprimierten Kernel auf Ubuntu erhält

    – Pavan Manjunath

    17. April 2012 um 8:57 Uhr

  • Groß! Ich habe meine Antwort bearbeitet, um diese Informationen auch hinzuzufügen, damit sie anderen in Zukunft helfen

    – Pavan Manjunath

    17. April 2012 um 9:16 Uhr

Für Emacs-Benutzer: hier‘s ist ein wichtiger Modus, um innerhalb des Stack-Trace einfach herumzuspringen (benutzt addr2line im Inneren).

Haftungsausschluss: Ich habe es geschrieben 🙂

Aufstoßen diese Antwort Sie müssen verwenden faddr2line

In meinem Fall hatte ich die folgende abgeschnittene Anrufverfolgung:

[  246.790938][   T35] Call trace:
[  246.794075][   T35]  __switch_to+0x10c/0x180
[  246.798348][   T35]  __schedule+0x278/0x6e0
[  246.802531][   T35]  schedule+0x44/0xd0
[  246.806368][   T35]  rpm_resume+0xf4/0x628
[  246.810463][   T35]  __pm_runtime_resume+0x94/0xc0
[  246.815257][   T35]  macb_open+0x30/0x2b8
[  246.819265][   T35]  __dev_open+0x10c/0x188

und lief folgendes in der Mainline-Linux-Kernel:

./scripts/faddr2line vmlinux macb_open+0x30/0x2b8

Ausgabe geben

macb_open+0x30/0x2b8:
pm_runtime_get_sync at include/linux/pm_runtime.h:386
(inlined by) macb_open at drivers/net/ethernet/cadence/macb_main.c:2726

1158870cookie-checkWie kann man den Stack-Trace (vom Kernel oder Core-Dump) sinnvoll nutzen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy