通过KGDB调试模块

时间:2011-06-07 05:25:13

标签: debugging kernel-module

我想调试我的内核模块。为此,我试图在我的do_one_initcall被调用之前kernel / module.c init_module处设置一个断点,但它正在显示

  

无法访问地址内存   0x802010a0

以下是我正在使用的Makefile

obj-m := hello.o

KDIR=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)

EXTRA_CFLAGS += -g

all:
        make -C $(KDIR) M=$(PWD) modules

clean:
        make -C $(KDIR) M=$(PWD) clean

请告诉我可能是什么问题。

1 个答案:

答案 0 :(得分:9)

只有在插入模块时才会设置可加载内核模块在内存中的位置。 在模块函数上设置断点时,gdb会查询模块文件(.ko)以获取地址,这是错误的。您需要通知gdb模块的实际位置。

您可以参考this book(第4章,调试器和相关工具部分)以获取更多信息,但这是我为此设计的简短程序。

  • machine1是已调试的机器。
  • machine2是运行调试器的机器。

  1. 在machine1上,运行modpbrobe your_module_name
  2. 在machine1上,运行以下shell命令:
    MODULE_NAME=your_module_name
    MODULE_FILE=$(modinfo $MODULE_NAME| awk '/filename/{print $2}')
    DIR="/sys/module/${MODULE_NAME}/sections/"
    echo add-symbol-file $MODULE_FILE $(cat "$DIR/.text") -s .bss $(cat "$DIR/.bss") -s .data $(cat "$DIR/.data")
    您应该获得类似于以下内容的输出:
    add-symbol-file /lib/modules/.../your_module_name.ko 0xffffffffa0110000 -s .bss 0xffffffffa011b948 -s .data 0xffffffffa011b6a0
  3. 在machine2上,运行gdb vmlinux
  4. 在machine2上,在gdb控制台上,运行第2阶段中最终命令的输出。
  5. 在机器2上,在gdb控制台上,通过运行target remote /dev/ttyS0连接到machine1(假设您的串口位于ttyS0)
  6. 在machine1上,运行echo g > /proc/sysrq-trigger。机器将冻结
  7. 在机器2上,在gdb控制台上,根据需要设置断点。
  8. 继续调试。应该在需要时触发断点。
  9. 可能存在阻止您设置断点的其他问题,但这是跨越的主要障碍。