The FreeBSD Developers' Handbook has a chapter entitled Debugging Loadable Modules Using GDB.

The information in that chapter is somewhat out of date. Here I give simple (that is, less general) instructions which will work with recent (RELENG_6, 7.0-CURRENT) kernels.

Here we assume that you have a recipe to make the kernel panic in some function of your module (or at least, you find it likely that using your module will result in a panic), and you want to get an useable backtrace.

  1. Create a kernel with debugging enabled. (I don't go into details here, consult with Developers' Handbook.)
  2. Compile your module with something similar to make DEBUG_FLAGS=-g.

  3. Load the module (eg., kldload foo.ko).

  4. Compute the relocation address for the module's code as it's written in Developers' Handbook.
  5. Do whatever you need to do for panicking your system.
  6. Dump the kernel (cf. Developers' Handbook).
  7. Start kgdb on your kernel and dump (eg.,
     kgdb /usr/obj/usr/src/sys/GENERIC/kernel.debug /var/crash/vmcore.2

    recently, there is no separate kernel.debug, so now the above will look like

     kgdb /usr/obj/usr/src/sys/GENERIC/kernel /var/crash/vmcore.2

    ) and add the module's symbol table as it's written in Developers' Handbook, using the pre-computed relocation address, and the debug version of your module (eg., foo.ko.debug).

  8. Get the backtrace with the bt command.

You can automate the computation of the relocation address with the help of the following Ruby script:

modpath = $*[0]

txtoffset = open("|objdump --section-headers #{modpath}") { |f|
  f.readlines
}.grep(/\s\.text\s/)[0].split[-2].to_i(16)

memoffset = open("|kldstat"){ |f| f.readlines }.grep(
  /#{Regexp.quote File.basename(modpath)}$/
)[0].split[2].to_i(16)

puts "0x#{(txtoffset + memoffset).to_s(16)}"

(If you save it as modaddr.rb, and make it executable, you can run it like modaddr.rb foo.ko, assuming foo is loaded.)

DebuggingModules (last edited 2008-06-17 21:38:24 by localhost)