可装载模块调试的总结

 

1、首先关于kernel的一些总结:

内核在make modules的时候,会生成模块的可执行文件,make modules_install会把这写可执行文件都copy到/lib/modules/X.Y.Z目录下。该目录下都是模块,还有一个build目录,是源码目录的链接。

再总结一些kgdb调试的内容:

2、目标机:

目标机进入内核调试状态有两种方式:

方式一:在grub引导时就加入启动参数

kgdboc=ttyS0,115200 kgdbwait

echo g>/proc/sysrq-trigger

此时,调试机进入假死状态,等待远程gdb的链接。

#insmod hello.ko(/root/mod1/)

宿主机:

#stty speed </dev/ttyS0

#gdb -q vmlinux(vmlinux是一个二进制文件)

(gdb)set debug remote 1(显示调试过程中跟gdb通信的数据包)

(gdb)target remote /dev/ttyS0

(gdb) b kernel/module.c:3042(在模块的初始化函数处设置断点)

(gdb)c(此时客户端从假死状态中退出)

此时目标端运行insmod之后,会命中断点,接下来就能进行调试工作。

如果此时想查看模块的加载信息,可以自定义gdb的宏lsmod。然后对该宏进行加载。

(gdb)source lsmod

(gdb)lsmod

在linux系统中,模块的初始地址会保存在结构体struct module所构成的链表中。

我们首先获取当前模块的module结构体的起始地址。

(gdb)set $m=(struct module *)0xF8137000

(gdb)p $m->module_core

(gdb)p $m->module_init

此时就可以加载模块的符号信息。

(gdb)add-symbol-file /root/mod1/hello.ko module_core .init.text module_init

加载完成之后,就可以在模块的源码中设置断点了,注意:此时设置断点的方式必须为硬件断点。

(gdb)hbreak hello_init

问题:为什么在源码设置断点,调试的vmlinux会命中呢?

vmlinux是源码的符号表,将源码的符号(函数名等)跟地址对应起来。这样,gdb在设置断点的时候,在符号(函数名,变量等)处设置断点就相当于在vmlinux中的地址处设置断点了。 

3、补充

调试模块的时候,目标机和主机都需要有模块的源码,而且目录结构要一样,不然,在运行gdb的主机(宿主机)上找不到相应的内容。


你可能感兴趣的:(可装载模块调试)