This method to debug kernel uses the inbuilt gdb server exposed by Qemu for a running virtual machine. This is superior to just running gdb on the kernel, since Qemu monitor provides many more options.

A. Preparation
Tell Qemu to provide a way to connect to it's monitor. We will use unix domain socket here.

1) If you are using virt-manager (libvirt/virsh) to manage your Qemu virtual machines (else skip).
Add a qemu monitor interface to VM.

virsh edit

Make the following changes to config file.

(i) change

to

(ii) Add the following lines
Use a different id than monitor2, if it already has been used. Also ensure that the file "/var/lib/libvirt/qemu//monitor2.sock" isn't already being used.


2) If you are running Qemu directly from command line (else skip).

Add the following to your qemu command line (the highlighted part).

qemu-system-x86_64 ... -chardev socket,id=charmonitor2,path=/var/lib/libvirt/qemu//monitor2.sock,server,nowait -mon chardev=charmonitor2,id=monitor2,mode=readline

B. Run
Run the virtual machine.

C. Connect to Qemu monitor

(The commands to be typed are in bold, rest is output from the console.)

sudo socat - UNIX-CONNECT:/var/lib/libvirt/qemu//monitor2.sock

Now you will see the following command prompt.

(qemu)
(qemu) help info
help info
info balloon -- show balloon information
info block [-n] [-v] [device] -- show info of one block device or all block devices (-n: show named nodes; -v: show details)
info block-jobs -- show progress of ongoing block device operations
info blockstats -- show block device statistics
info capture -- show capture information
info chardev -- show the character devices
info cpus -- show infos for each CPU
info cpustats -- show CPU statistics
. . .
info ioapic -- show io apic state
info iothreads -- show iothreads
info irq -- show the interrupts statistics (if available)
info jit -- show dynamic compiler info
info kvm -- show KVM information
info lapic -- show local apic state
info mem -- show the active virtual memory mappings
info memdev -- show memory backends
info memory-devices -- show memory devices
...
info mtree -- show memory tree
. . .


D. Start gdb server

(qemu) gdbserver
gdbserver
Waiting for gdb connection on device 'tcp::1234'
(qemu)


E. Connect to the started gdb server from host, or from a remote machine.

gdb vmlinux
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
native_safe_halt () at ./arch/x86/include/asm/irqflags.h:50

The first line loads debugging symbols from vmlinux files produced from compiling the kernel. It can also be extracted from vmlinuz file present in the "/boot" folder.
As you can see in the third line that the virtual machine is halted. To continue running the vm enter continue command.


(gdb) continue


Resources