我想调试我的内核模块。为此,我试图在我的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
请告诉我可能是什么问题。
答案 0 :(得分:9)
只有在插入模块时才会设置可加载内核模块在内存中的位置。 在模块函数上设置断点时,gdb会查询模块文件(.ko)以获取地址,这是错误的。您需要通知gdb模块的实际位置。
您可以参考this book(第4章,调试器和相关工具部分)以获取更多信息,但这是我为此设计的简短程序。
machine2是运行调试器的机器。
modpbrobe your_module_name
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
gdb vmlinux
。target remote /dev/ttyS0
连接到machine1(假设您的串口位于ttyS0)echo g > /proc/sysrq-trigger
。机器将冻结