diff options
Diffstat (limited to 'microkernel/mach/gnumach/debugging.mdwn')
-rw-r--r-- | microkernel/mach/gnumach/debugging.mdwn | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/microkernel/mach/gnumach/debugging.mdwn b/microkernel/mach/gnumach/debugging.mdwn index 9534c758..bcff970e 100644 --- a/microkernel/mach/gnumach/debugging.mdwn +++ b/microkernel/mach/gnumach/debugging.mdwn @@ -73,15 +73,102 @@ and then type continue, to let Mach continue execution. The debugger will be ent struct db_watchpoint watch = { .task = NULL, .loaddr= 0x40e, .hiaddr = 0x40e+2, .link = NULL}; db_set_hw_watchpoint(&watch, 0); +To discover what an arbitrary address points to, try + + whatis 0x123400 + # GDB in QEMU When you're [[running_a_system_in_QEMU|hurd/running/qemu]] you can directly [use GDB on the running -kernel](http://www.nongnu.org/qemu/qemu-doc.html#SEC48). +kernel](https://www.qemu.org/docs/master/system/gdb.html). + +When debugggin 32-bit gnumach, you can specify the kernel file in the +command line with the `-kernel` option and the boot modules with +`-initrd`, as described in [[hurd/running/qemu]]. This however does +not work for 64-bit gnumach, due to a [limitation in +qemu](https://gitlab.com/qemu-project/qemu/-/issues/243). To overcome +this, you can either patch qemu to enable multiboot also for 64-bit +ELF, or build a bootable ISO image with `grub-mkrescue`. + +To enable the gdbserver on a running instance, you need to access the +qemu monitor and use the `gdbserver` command. For example, with +libvirt/virt-manager + + $ virsh --connect qemu:///session qemu-monitor-command --domain hurd --hmp --cmd gdbserver + +Otherwise, if you start qemu manually, you can use the `-s` and `-S` +shortcuts, that will open a tcp connection on port 1234 and wait for +gdb to attach before starting the vm. + +If you don't need a graphical interface, e.g. you're working on the +boot process, you could use stdio as an emulated serial port with +`-nographic`, and append `console=com0` to the kernel command line, +either in grub or with the `-append` option. + +Once qemu has started, you can connect to the gdbserver with + + $ gdb gnumach + ... + (gdb) target remote :1234 + (gdb) c + +You can also automate some steps with a `.gdbinit` file in your +working directory. For example: + + set print pretty + target remote :1234 + # let's set some breakpoints + b Panic + b c_boot_entry + b user_bootstrap + b ../i386/intel/pmap.c:1981 + # we can also refer to virtual addresses in userspace + b *0x804901d + # this shows the instruction being executed + display/i $pc + layout asm ## [[open_issues/debugging_gnumach_startup_qemu_gdb]] +## Debug 64-bit gnumach + +[[build|microkernel/mach/gnumach/building/]] 64-bit gnumach with: + + $ export CFLAGS=-g + $ ../configure --enable-kdb ... + +run a spare Hurd vm (prepare for data loss in vm): + +* `kvm -net user,hostfwd=tcp:127.0.0.1:2222-:22 -net nic,model=e1000 -drive file=$(echo debian-hurd*.img),cache=writeback -m 1G` +* `cd gnumach/build` +* `scp -P 2222 gnumach.gz user@127.0.0.1:/home/user/` +* You may copy `gnumach.gz` (also create new grub entry) or replace using `mv /home/user/gnumach.gz /boot/gnumach-xxx.gz` +* Shutdown vm. +* Append `console=com0` in boot menu and switch to console mode in qemu. (We have known issues with vga output for 64-bit.) +* You may load only required modules for debugging. +* `kvm -s -S -net user,hostfwd=tcp:127.0.0.1:2222-:22 -net nic,model=e1000 -drive file=$(echo debian-hurd*.img),cache=writeback -m 1G` (note: `-s -S` added.) +* `gdb ./gnumach` +* `(gdb) target remote :1234` +* Press `c` to continue booting. + + +example `/boot/grub/grub.cfg`: + + multiboot /boot/gnumach-1.8-486.gz root=part:2:device:hd0 console=com0 + ... + echo 'Loading the Hurd ...' + module /hurd/ext2fs.static ext2fs --readonly \ + --multiboot-command-line='${kernel-command-line}' \ + \ + --host-priv-port='${host-port}' --device-master-port='${device-port}' \ + --exec-server-task='${exec-task}' -T typed '${root}' \ + '$(fs-task=task-create)' '$(task-resume)' + module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)' + + + # Code Inside the Kernel |