Ich würde versuchen:
(gdb) target remote localhost:1234
(gdb) continue
Die Verwendung der Option „-s“ lässt qemu auf Port tcp::1234 lauschen, mit dem Sie sich als localhost:1234 verbinden können, wenn Sie sich auf demselben Computer befinden. Die '-S'-Option von Qemu bewirkt, dass Qemu die Ausführung stoppt, bis Sie den Continue-Befehl geben.
Das Beste wäre wahrscheinlich, sich ein anständiges GDB-Tutorial anzusehen, um mit dem klarzukommen, was Sie tun. Dieser hier sieht ganz nett aus.
Schritt-für-Schritt-Verfahren auf Ubuntu 16.10-Host getestet
Um schnell von vorne anzufangen, habe ich ein minimales vollautomatisiertes QEMU + Buildroot-Beispiel erstellt unter:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Major Schritte werden unten behandelt.
Besorgen Sie sich zuerst ein Root-Dateisystem rootfs.cpio.gz
. Wenn Sie eine benötigen, ziehen Sie Folgendes in Betracht:
- mindestens
init
-nur ausführbares Image:https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579 - ein interaktives Busybox-System:https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Dann auf dem Linux-Kernel:
git checkout v4.15
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
-initrd rootfs.cpio.gz -S -s \
-append nokaslr
Angenommen, Sie möchten auf einem anderen Terminal innerhalb des Linux-Kernelbaums mit dem Debuggen ab start_kernel
beginnen :
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set arch i386:x86-64' \
-ex 'target remote localhost:1234'
und wir sind fertig!!
Für Kernel-Module siehe:Wie debuggt man Linux-Kernel-Module mit QEMU?
Für Ubuntu 14.04, GDB 7.7.1, hbreak
wurde benötigt, break
Software-Haltepunkte wurden ignoriert. In 16.10 nicht mehr der Fall. Siehe auch:https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
Das chaotische disconnect
und was danach kommt, um den Fehler zu umgehen:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Verwandte Threads:
- https://sourceware.org/bugzilla/show_bug.cgi?id=13984 könnte ein GDB-Fehler sein
- Remote 'g'-Paketantwort ist zu lang
- http://wiki.osdev.org/QEMU_and_GDB_in_long_mode osdev.org ist wie immer eine großartige Quelle für diese Probleme
- https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html
nokaslr
:https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb/421287#421287
Bekannte Einschränkungen:
- der Linux-Kernel unterstützt nicht (und lässt sich nicht einmal ohne Patches kompilieren) mit
-O0
:Wie deoptimiere ich den Linux-Kernel und kompiliere ihn mit -O0? - GDB 7.11 wird Ihr Gedächtnis bei einigen Arten der Tab-Vervollständigung sprengen, selbst nach
max-completions
Fix:Unterbrechung der Tab-Vervollständigung bei großen Binärdateien Wahrscheinlich ein Sonderfall, der in diesem Patch nicht behandelt wurde. Also eineulimit -Sv 500000
ist eine kluge Aktion vor dem Debuggen. Ist speziell explodiert, als ich mit der Tabulatortastefile<tab>
abgeschlossen habe fürfilename
Argument vonsys_execve
wie in:https://stackoverflow.com/a/42290593/895245
Siehe auch:
- https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst offizielle Linux-Kernel-"Dokumentation"
- Linux-Kernel-Live-Debugging, wie es gemacht wird und welche Tools verwendet werden?
Die Antwort von BjoernID hat bei mir nicht wirklich funktioniert. Nach der ersten Fortsetzung wird kein Breakpoint erreicht und bei Interrupt sehe ich Zeilen wie:
0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]
Ich denke, das hat etwas mit unterschiedlichen CPU-Modi zu tun (Real-Modus im BIOS vs. Long-Modus, wenn Linux gebootet hat). Wie auch immer, die Lösung besteht darin, QEMU zuerst ohne Wartezeit auszuführen (d.h. ohne -S
):
qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s
In meinem Fall musste ich während des Bootens etwas unterbrechen, also führte ich nach einigen Dezisekunden den gdb-Befehl aus. Wenn Sie mehr Zeit haben (z. B. wenn Sie ein manuell geladenes Modul debuggen müssen), spielt das Timing keine Rolle.
gdb
ermöglicht es Ihnen, Befehle anzugeben, die beim Start ausgeführt werden sollen. Das macht die Automatisierung etwas einfacher. Um sich mit QEMU zu verbinden (das jetzt bereits gestartet sein sollte), eine Funktion zu unterbrechen und die Ausführung fortzusetzen, verwenden Sie:
gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux