Alexander Krause
strg+c
unterbrochen werdenUnterstützt verschiedene Ziele (targets), wie z. B. i386, amd64, …
Erweiterbar um weitere Ziele mittels GDB-Stub
(Ziel muss nur das GDB-Protokoll implementieren)
Können wir den GNU Debugger einfach für einen Betriebssystemkern (hier: Linux) nutzen?
Nein!
Problem: GDB läuft selbst ein Anwendungsprozess und soll der Betriebssystemkern untersuchen. Wir müssen von von außen an den Kern. Aber wie?
Wie kann ich einen laufenden Betriebssystemkern oder einen laufenden Computer untersuchen?
Lässt sich „einfach” über einen GDB bedienen
Benötigt zwei Computer:
Device under Test (DUT) und Entwicklungsmaschine
Aus dem untersuchten System die Kontrolle an den GDB übergeben
echo g > /proc/sysrq-trigger
Kernparameter kgdbwait
Verweilt nicht zu lange im GDB, bevor Ihr c
drückt. Ansonsten beschwert sich der Linux-Kern
[ 116.011870][ C0] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 50930.300 msecs
Pro
Contra
Und nu?
strg+c
) möglich(Geht bei uns auch mit dem Parameter -g XX/vmlinux
für das Skript boot.sh
)
Quellen
(GCC-Erweiterung mcount)
Frontend
Wichtige Erkenntnis: Abwägung zwischen spezifische Informationen sind direkt verfügbar vs. universell im Kern einsetzbar (Danke an Julia Evans für ihre schöne Einteilung und Brendan Gregg)
int3
(auf x86)int3
)
jmp
-Instruktion statt int3
Wir schauen uns SystemTap an. Warum? Weil ich „nur” SystemTap kann. 😎
Ursprüngliches Konzept von Frank Ch. Eigler et al. [4]
Nutzt verschiedene Backends:
kprobes, uprobes, ebpf, …
C-ähnliche Sprache zum Erstellen von Skripten
Kapselung von häufig-genutzten Funktionen in Tapsets
Zustand modifizieren oder echten C-Code einbauen mit dem Guru-Mode (-g
)
Schaut gerne in den Beginners Guide
open()
-v
: Erhöhe das Log-Level-t
: Erhebe Timing-Informationen während der Ausführung und gebe sie aus-r
: Pfad zum Linux-Quellcode-Verzeichnis, hier /mnt/linux
test.stp
syscall.open
kernel.function("foo@bar.c")
→ Funktion foo()
in Datei bar.c
kernel.function("*@bar.c")
→ jede Funktion in Datei bar.c
kernel.statement("*@fs/namei.c:3080")
→ Zeile 3080 in Datei fs/namei.c
Ausgabe: