用 GDB 调试可加载模块ko

用 GDB 调试可加载模块

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

  首先, 需要在编译模块时加入调试信息:
# cd /sys/modules/linux
# make clean; make COPTS=-g

   如果使用远程 GDB, 您可以在目标机上执行 kldstat 来了解模块的加载位置:(linux中貌似没有这个命令,那直接看/proc/modules的信息)
# 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)

   现在就可以使用模块的全部符号了。(不过貌似没法增加断点,有个毛用,看看有没有方法解决)


猜你喜欢

转载自blog.csdn.net/oushaojun2/article/details/80509672