通过KGDB调试模块

cp5*_*662 5 debugging kernel-module

我想调试我的内核模块.对于我试图把一个断点do_one_initcallkernel/ 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
Run Code Online (Sandbox Code Playgroud)

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

Nir*_*Nir 9

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

您可以参考本书(第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")
    Run Code Online (Sandbox Code Playgroud) 你应该得到类似于以下的输出:
    add-symbol-file /lib/modules/.../your_module_name.ko 0xffffffffa0110000 -s .bss 0xffffffffa011b948 -s .data 0xffffffffa011b6a0
    Run Code Online (Sandbox Code Playgroud)
  3. 在machine2上运行gdb vmlinux.
  4. 在machine2上,在gdb控制台上,在第2阶段运行final命令的输出.
  5. 在机器2上,在gdb控制台上,通过运行连接到machine1 target remote /dev/ttyS0(假设您的串口位于ttyS0)
  6. 在machine1上运行echo g > /proc/sysrq-trigger.机器会冻结
  7. 在machine2上,在gdb控制台上,根据需要设置断点.
  8. 继续调试.应该在需要时触发断点.
可能存在阻止您设置断点的其他问题,但这是跨越的主要障碍.