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.
- On machine1, run
modpbrobe your_module_name
- On machine1, run the following shell commands:
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")
you should get an output similar to the following: 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.
There could be other issues that prevent you from setting the breakpoint, but this is the main hurdle to cross.