I want to debug my kernel module. For that I am trying to put a breakpoint at do_one_initcall
in kernel
/module.c
just before my init_module
gets called but it's displaying
Cannot access memory at address 0x802010a0
Below is the Makefile
which I am using:
obj-m := hello.o
KDIR=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)
EXTRA_CFLAGS += -g开发者_StackOverflow社区
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
Please suggest me what could be the problem.
A loadable kernel module's location in the memory is set only upon insertion of the module. When you set a breakpoint on a module function, gdb consults the module file (.ko) for the address, which is wrong. You need to inform gdb of the actual location of the module.
You can consult this book (chapter 4, Debuggers and related tools section) for more information, but here's a short procedure that I devised for doing that.
- machine1 is the debugged machine.
machine2 is the machine running the debugger.
- On machine1, run
modpbrobe your_module_name
- On machine1, run the following shell commands:
you should get an output similar to the following: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
- On machine2, run
gdb vmlinux
. - On machine2, on the gdb console, run the output of the final command in stage 2.
- On machine2, on the gdb console, connect to machine1 by running
target remote /dev/ttyS0
(assuming your serial port is at ttyS0) - On machine1, run
echo g > /proc/sysrq-trigger
. The machine will freeze - On machine2, on the gdb console, set the breakpoint as you wish.
- Continue debugging. The breakpoint should be triggered when it needs to.
精彩评论