10.7 用 GDB 调试可加载模块

  在调试发生于模块中的 panic, 或者使用远程 GDB 调试使用动态模块的机器时, 需要告诉 GDB 如何获取这些模块的符号信息。

  首先, 需要在编译模块时加入调试信息:

# cd /sys/modules/linux
# make clean; make COPTS=-g

  如果使用远程 GDB, 您可以在目标机上执行 kldstat 来了解模块的加载位置:

# kldstat
Id Refs Address    Size     Name
 1    4 0xc0100000 1c1678   kernel
 2    1 0xc0a9e000 6000     linprocfs.ko
 3    1 0xc0ad7000 2000     warp_saver.ko
 4    1 0xc0adc000 11000    linux.ko

  如果您正调试内核崩溃转存数据, 则需要访问 linker_files 表, 从 linker_files->tqh_first 开始, 并沿 link.tqe_next 指针寻找包含您所查找的 filename 的项。 那个项的 address 成员就是模块的加载地址。

  接下来, 您需要找出模块中代码节 (text section) 的偏移量:

# objdump --section-headers /sys/modules/linux/linux.ko | grep text
  3 .rel.text     000016e0  000038e0  000038e0  000038e0  2**2
 10 .text         00007f34  000062d0  000062d0  000062d0  2**2

  您需要的是 .text 节, 在前述例子中, 是 10 号节。 第四个十六进制字段 (或者说从左往右数第六个字段) 是代码节在文件中的偏移量。 将这一偏移量与模块的加载地址相加, 就可以得到模块的代码在重定位之后的地址了。 在我们的例子中, 可以得到 0xc0adc000 + 0x62d0 = 0xc0ae22d0。 接下来就可以用 add-symbol-file 来告诉 GDB 关于调试模块的信息:

(kgdb) add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0
add symbol table from file "/sys/modules/linux/linux.ko" at text_addr = 0xc0ae22d0?
(y or n) y
Reading symbols from /sys/modules/linux/linux.ko...done.
(kgdb)

  现在就可以使用模块的全部符号了。

本文档和其它文档可从这里下载:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读文档,如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.