Index: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc =================================================================== --- documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc +++ documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc @@ -533,32 +533,40 @@ [[kerneldebug-online-gdb]] == On-Line Kernel Debugging Using Remote GDB +The FreeBSD kernel provides a second on-line debugging backend: man:gdb[4]. This feature has been supported since FreeBSD 2.2, and it is actually a very neat one. -GDB has already supported _remote debugging_ for a long time. +GDB has supported _remote debugging_ for a long time. This is done using a very simple protocol along a serial line. Unlike the other methods described above, you will need two machines for doing this. One is the host providing the debugging environment, including all the sources, and a copy of the kernel binary with all the symbols in it, and the other one is the target machine that simply runs a similar copy of the very same kernel (but stripped of the debugging information). -You should configure the kernel in question with `config -g` if building the "traditional" way. -If building the "new" way, make sure that `makeoptions DEBUG=-g` is in the configuration. -In both cases, include `DDB` in the configuration, and compile it as usual. -This gives a large binary, due to the debugging information. -Copy this kernel to the target machine, strip the debugging symbols off with `strip -x`, and boot it using the `-d` boot option. +In order to use remote GDB, ensure that the following options are present in your kernel configuration: +[.programlisting] +.... +makeoptions DEBUG=-g +options KDB +options DDB +options GDB +.... + +Note that the `DDB` option is not _strictly_ required, but is assumed in the example below. +The `DDB` and `GDB` options are turned off by default on `stable` and `release` branches. + +Once built, copy the kernel to the target machine, and boot it using the `-d` boot option to enter the debugger at boot time. Connect the serial line of the target machine that has "flags 080" set on its uart device to any serial line of the debugging host. See man:uart[4] for information on how to set the flags on an uart device. + Now, on the debugging machine, go to the compile directory of the target kernel, and start `gdb`: [source,bash] .... % kgdb kernel -GDB is free software and you are welcome to distribute copies of it - under certain conditions; type "show copying" to see the conditions. -There is absolutely no warranty for GDB; type "show warranty" for details. -GDB 4.16 (i386-unknown-freebsd), -Copyright 1996 Free Software Foundation, Inc... -(kgdb) +GNU gdb (GDB) 10.2 [GDB v10.2 for FreeBSD] +Copyright (C) 2021 Free Software Foundation, Inc. +... +(kgdb) .... Initialize the remote debugging session (assuming the first serial port is being used) by: @@ -568,31 +576,32 @@ (kgdb) target remote /dev/cuau0 .... -Now, on the target host (the one that entered DDB right before even starting the device probe), type: +Now, on the target host (the one that entered KDB right before even starting the device probe), enter 'gdb' at the prompt: [source,bash] .... -Debugger("Boot flags requested debugger") -Stopped at Debugger+0x35: movb $0, edata+0x51bc +KDB: enter: Boot flags requested debugger +[ thread pid 0 tid 0 ] +Stopped at kdb_enter+0x37: movq $0,0x12a2246(%rip) db> gdb +(ctrl-c will return control to ddb) +Switching to gdb back-end .... -DDB will respond with: - -[source,bash] -.... -Next trap will enter GDB remote protocol mode -.... +[NOTE] +==== +The `debug.kdb.current` sysctl can be used to select the primary debugger backend. +Setting its value to `gdb` allows the previous step to be skipped, as the kernel will enter GDB immediately. +The supported backends are listed by `debug.kdb.available`. +==== -Every time you type `gdb`, the mode will be toggled between remote GDB and local DDB -In order to force a next trap immediately, simply type `s` (step). Your hosting GDB will now gain control over the target kernel: [source,bash] .... Remote debugging using /dev/cuau0 -Debugger (msg=0xf01b0383 "Boot flags requested debugger") - at ../../i386/i386/db_interface.c:257 +kdb_enter (why=0xffffffff81359321 "bootflags", msg=) + at /usr/src/sys/kern/subr_kdb.c:479 (kgdb) ....