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}}}).
 1. Get the backtrace with the {{{bt}}} command.

You can automate the computation of the relocation address with the help of the following
[[http://www.freshports.org/lang/ruby18|Ruby]] script:
{{{
#!/usr/bin/env ruby

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.txt
  • Last modified: 2026/10/12 10:55
  • (external edit)