Yo intentaría:
(gdb) target remote localhost:1234
(gdb) continue
El uso de la opción '-s' hace que qemu escuche en el puerto tcp::1234, al que puede conectarse como localhost:1234 si está en la misma máquina. La opción '-S' de Qemu hace que Qemu detenga la ejecución hasta que usted dé el comando de continuar.
Lo mejor probablemente sería echar un vistazo a un tutorial GDB decente para llevarse bien con lo que está haciendo. Este se ve bastante bien.
Procedimiento paso a paso probado en host Ubuntu 16.10
Para comenzar desde cero rápidamente, hice un ejemplo mínimo de QEMU + Buildroot totalmente automatizado en:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Mayor Los pasos se describen a continuación.
Primero obtenga un sistema de archivos raíz rootfs.cpio.gz
. Si necesita uno, considere:
- un
init
mínimo -solo imagen ejecutable:https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579 - un sistema interactivo Busybox:https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Luego en el kernel de Linux:
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
En otra terminal, desde el interior del árbol del kernel de Linux, supongamos que desea iniciar la depuración desde start_kernel
:
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'
¡¡y hemos terminado!!
Para los módulos del kernel, consulte:¿Cómo depurar los módulos del kernel de Linux con QEMU?
Para Ubuntu 14.04, GDB 7.7.1, hbreak
se necesitaba, break
Se ignoraron los puntos de interrupción del software. Ya no es el caso en 16.10. Consulte también:https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
El desordenado disconnect
y lo que viene después es solucionar el error:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Temas relacionados:
- https://sourceware.org/bugzilla/show_bug.cgi?id=13984 podría ser un error de GDB
- La respuesta del paquete 'g' remoto es demasiado larga
- http://wiki.osdev.org/QEMU_and_GDB_in_long_mode osdev.org es, como de costumbre, una excelente fuente para estos problemas
- 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
Limitaciones conocidas:
- el kernel de Linux no es compatible (y ni siquiera compila sin parches) con
-O0
:¿Cómo desoptimizar el kernel de Linux y compilarlo con -O0? - GDB 7.11 te hará perder la memoria en algunos tipos de finalización de pestañas, incluso después del
max-completions
corrección:Interrupción de finalización de tabulación para binarios grandes Probablemente algún caso de esquina que no se cubrió en ese parche. Así que unulimit -Sv 500000
es una sabia acción antes de la depuración. Explotó específicamente cuando tabulé completandofile<tab>
para elfilename
argumento desys_execve
como en:https://stackoverflow.com/a/42290593/895245
Véase también:
- https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst "documentación" oficial del kernel de Linux
- Depuración en vivo del kernel de Linux, ¿cómo se hace y qué herramientas se utilizan?
La respuesta de BjoernID realmente no funcionó para mí. Después de la primera continuación, no se alcanza ningún punto de interrupción y en la interrupción, vería líneas como:
0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]
Supongo que esto tiene algo que ver con los diferentes modos de CPU (modo real en BIOS versus modo largo cuando Linux ha arrancado). De todos modos, la solución es ejecutar QEMU primero sin esperar (es decir, sin -S
):
qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s
En mi caso, necesitaba romper algo durante el arranque, así que después de unos decisegundos, ejecuté el comando gdb. Si tiene más tiempo (por ejemplo, necesita depurar un módulo que se carga manualmente), entonces el tiempo realmente no importa.
gdb
le permite especificar los comandos que deben ejecutarse cuando se inicia. Esto hace que la automatización sea un poco más fácil. Para conectarse a QEMU (que ahora ya debería estar iniciado), interrumpa una función y continúe con la ejecución, use:
gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux