Introduction
This HOWTO shows how to set up a test environment for debugging the NetBSD kernel with full debug symbols and source using a pair of QEMU virtual machines,
The Host System
You need a computer running NetBSD, Linux, or some other Unix-like OS, with at least 10 gigabytes of available disk space (the "host system"). These instructions have been most recently tested on a NetBSD/amd64 9.2 host system.
Install the following packages from pkgsrc:
- emulators/qemu
- misc/py-anita
If your host system doesn't have pkgsrc, you can use another package system to install qemu, the Python pexpect library, and genisoimage or mkisofs. Also download and install the most recent anita package from http://www.gson.org/netbsd/anita/download/.
The Target System
The target system is the NetBSD system whose kernel you want to debug. The examples below assume NetBSD-current/amd64, but the i386 port will also work; just replace each instance of "amd64" in the commands below by "i386", and "qemu-system-x86_64" by "qemu-system-i386".
Other NetBSD ports should also work in principle, but in practice none of them do, for various reasons: they are either not supported by QEMU, not supported by anita, supported by anita only using install media that lack debug or source sets, fail to install, or have networking issues when run under QEMU.
The host and target system do not need to be the same architecture.
Installing the Target System
Install the target system in a virtual machine, including the debug symbols and source code:
$ anita --workdir work --disk-size 10G --memory-size 256M \ --sets kern-GENERIC,modules,base,etc,comp,debug,games,man,misc,tests,text,syssrc,src,sharesrc,gnusrc \ install http://nycdn.netbsd.org/pub/NetBSD-daily/HEAD/latest/amd64/
This will produce a disk image in work/wd0.img
.
Booting the VMs
Next, start two qemu virtual machines, one to run the kernel being debugged (the "target VM") and another to run the debugger (the "gdb VM").
The two VMs can run on the same host system and share a single hard disk image. The sharing is made possible by the qemu "-snapshot" option, which ensures that the disk image is treated as read-only by both VMs.
First start the target VM, enabling qemu's built-in GDB target stub on TCP port 1234:
$ qemu-system-x86_64 -nographic -snapshot -hda work/wd0.img -m 256 -gdb tcp::1234
If you don't want everyone on the Internet to be able to debug your target, make sure incoming connections on port 1234 are blocked in your firewall.
In a second terminal window, start the gdb VM:
$ qemu-system-x86_64 -nographic -snapshot -hda work/wd0.img -m 256
Log in to the gdb VM as root and set up the network. Use the
-w
option to dhcpcd
to work around
PR 56598:
login: root # dhcpcd -w
Start gdb on the gdb VM and connect to the target:
# gdb /netbsd (gdb) target remote my.host:1234
where my.host is the domain name or IP address of the
host system. Note that specifying localhost
or 127.0.0.1
will not work because they mean the GDB VM itself, not the host.
Now you should be able to get a stack trace and start debugging with full debug symbols and access to the source code:
(gdb) where (gdb) list
Qemu Tips
Here is a couple of useful qemu commands to know:
Ctrl-a b will send a break which will make the NetBSD VM enter the ddb kernel debugger.
Ctrl-a c will switch to the qemu monitor where you can enter commands like "quit" to exit qemu, or do things like saving/restoring the VM to/from a file.