Debugging 通过KGDB进行模块调试
我想调试我的内核模块。为此,我试图在Debugging 通过KGDB进行模块调试,debugging,kernel-module,Debugging,Kernel Module,我想调试我的内核模块。为此,我试图在kernel/module.c调用我的init\u模块之前,在do\u initcall中设置一个断点,但它正在显示 无法访问地址处的内存 0x802010a0 下面是我正在使用的Makefile: obj-m := hello.o KDIR=/lib/modules/$(shell uname -r)/build PWD=$(shell pwd) EXTRA_CFLAGS += -g all: make -C $(KDIR) M=$(P
kernel
/module.c
调用我的init\u模块之前,在do\u initcall
中设置一个断点,但它正在显示
无法访问地址处的内存
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
请告诉我可能的问题。可加载内核模块在内存中的位置仅在插入模块时设置。
当您在模块函数上设置断点时,gdb会查阅模块文件(.ko)以获取地址,这是错误的。您需要通知gdb模块的实际位置
您可以参考(第4章,调试器和相关工具部分)了解更多信息,但这里有一个我为此设计的简短过程
- machine1是调试过的机器
- machine2是运行调试器的机器。
在machine1上,运行modpbrobe您的\u模块\u名称
在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
在machine2上,运行gdb-vmlinux
在machine2上的gdb控制台上,运行阶段2中最后一个命令的输出
在machine2上的gdb控制台上,通过运行target remote/dev/ttyS0
连接到machine1(假设串行端口位于ttyS0)
在machine1上,运行echo g>/proc/sysrq trigger
。机器会结冰
在machine2的gdb控制台上,根据需要设置断点
继续调试。断点应在需要时触发
可能还有其他问题阻止您设置断点,但这是要跨越的主要障碍。myinsmod
成功,我看到mymodule_init
kprints在dmesg
中。但是我的modprobe
失败了。因此,modinfo
也会失败。你能提供一些见解吗?可能有几个原因。最简单的一点是,modprobe不知道您的模块,因为它查阅数据库,所以您不能执行modprobe my_module_file.ko
。相反,在使用depmod-a
将我的模块名称插入数据库后,需要执行modprobe my\u module\u name
。不过,出于这个目的,这并不重要。你知道你的名字和文件名,所以你可以简单地使用它们,而不是答案所暗示的。e、 g.模块名称=我的模块名称;MODULE_FILE=my_MODULE_FILE.ko
快速提示:您需要root用户才能在此处获取cat/sys/MODULE/MODULE名称/sections/*工作。。(否则它只显示值0x0)。@Nir不是应该在机器2上运行的addsymbol file
?我的意思是这个命令本身不是gdb命令吗?我不知道它怎么能在机器1上运行。还是我遗漏了什么?