Cannot debug init using "qemu -s -S" if init is compiled dynamically or if kvm is enabled
Host environment
- QEMU flavor: qemu-system-x86_64
- Operating system: Debian sid (as of 2022-10-22)
- OS/kernel version: Linux 6.0.0-1-amd64
- Architecture: x86_64
- QEMU version: QEMU emulator version 7.1.0 (Debian 1:7.1+dfsg-2+b1)
- QEMU command line:
qemu-system-x86_64 -daemonize -m 300M -s -S -kernel /vmlinuz -initrd /initrd.img -snapshot -append "root=/dev/sda init=/root/a.out" -drive file=/dev/sda,format=raw
Emulated/Virtualized environment
- Operating system: Debian sid (as of 2022-10-22)
- OS/kernel version: Linux 6.0.0-1-amd64
- Architecture: x86_64
Description of problem
I'm trying to connect from host to init process running in guest. I'm using this guide: https://qemu-project.gitlab.io/qemu/system/gdb.html . Everything works well, but there is two problems:
- Debugging stops to work if I add "-enable-kvm"
- Debugging stops to work if I remove "-static" when compiling init
Steps to reproduce
I have absolutely fresh Debian sid system (as of 2022-10-22). I create the following file on it:
#include <stdio.h>
int
main ()
{
printf ("a\n");
printf ("b\n");
for (;;);
}
Then I compile it so: gcc -static -g a.c
. Result is saved as /root/a.out
. Then I run sync; echo 3 > /proc/sys/vm/drop_caches; sync
to make sure this /root/a.out
actually got to disk.
Then I start the host system inside of qemu using well-known -snapshot /dev/sda
trick. Exact command is here:
qemu-system-x86_64 -daemonize -m 300M -s -S -kernel /vmlinuz -initrd /initrd.img -snapshot -append "root=/dev/sda init=/root/a.out" -drive file=/dev/sda,format=raw
(As you guessed, my disk has no partitions, it directly stores ext4 filesystem.)
Then I type on host gdb ./a.out
. And then inside of gdb I type target remote localhost:1234
, then br 7
(line 7 is printf ("b\n")
, then c
. Then guest OS boots and reaches init (i. e. /root/a.out
). And then gdb actually pauses on line 7. I. e. everything works!
But if I add -enable-kvm
to qemu command line OR remove -static
from gcc command line, then breakpoint doesn't work, i. e. gdb doesn't pause on breakpoint, the execution continues and the execution fails to infinite loop.