Spekii

Spekii

Monday, September 29, 2014

Debug a running kernel module with GDB and VirtualBox

In this post We are going to see how to debug a running kernel module of a guest VM from the host.

Setup VirtualBox

First you need to be sure that your kernel have to KGDB support. Then you have to setup your VM in order to add a virtual serial port. This serial port will be used for the remote debugging from the host. The following captures show how to setup it.
You see that a file is used for the serial port on the host. Before you we boot the VM we have to choose how to enable KGDB. Two solution here :
Boot kernel with arguments:
kgdboc=ttyS0,115200
or
Configure kgdboc after the kernel booted:
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
Now you have decided you can boot….

After the boot, the debugging…

First you have to sync up the kernel/module binaries and sources between the host and the guest. Personnally I simply use a rsync between the host and the VM, but a VirtualBox or a NFS shared folder should work.

Prepare the debugging on the host

Now we are going to link the virtual serial port created for the VM to a pseudo-termial.
socat -d -d /tmp/serial PTY:
Get the the pseudo-terminal used/returned by socat when starting gdb.
gdb ./vmlinux
(gdb) target remote /dev/pts/6

On the guest

By default gdb will not be able to resolve the symbols of the kernel module. So we need to get the .text, the .bss, the .data addresses.
sudo cat /sys/module/<module_name>/sections/.text
0xffffffffa0371000
sudo cat /sys/module/<module_name>/sections/.bss
0xffffffffa039b440
sudo cat /sys/module/<module_name>/sections/.data
0xffffffffa039a000
With only one line that can be pasted directly to GDB:
export MODULE=vrouter; echo add-symbol-file $MODULE.o $(cat /sys/module/$MODULE/sections/.text) -s .bss $(cat /sys/module/$MODULE/sections/.bss) -s .data $(cat /sys/module/$MODULE/sections/.data)
At this point we have to stop the execution of the kernel in order to load module symbols and to put breakpoints for examples.
echo g > /proc/sysrq-trigger 

Start the debugging

Now that you stop the execution of the kernel you should be able to load the module symbole.
(gdb) add-symbol-file module.o 0xffffffffa0371000 -s .bss 0xffffffffa039b440 -s .data 0xffffffffa039a000
(gdb) break xxxxxx