如何调试 Linux 内核模块 `init()` 中的问题?
Posted
技术标签:
【中文标题】如何调试 Linux 内核模块 `init()` 中的问题?【英文标题】:How to debug problems in Linux kernel module `init()`? 【发布时间】:2011-02-06 02:17:14 【问题描述】:我正在使用远程 (k)gdb 调试模块中的问题,该问题在加载时会导致崩溃,例如当init()
被调用时。
堆栈跟踪只是显示do_one_initcall(mod->init)
导致了崩溃。为了在 gdb 中加载符号文件,我需要获取模块文本部分的地址,并且要获取该地址,我需要加载模块。
因为busybox (1.16.1) 中的insmod
不支持-m
,所以我坚持使用grep modulename /proc/modules
+ 添加从nm
的偏移量来计算地址。
所以我在这里面临着鸡和蛋的问题——为了能够调试模块加载,我需要加载模块——但是为了加载模块,我需要调试问题...
所以我目前正在考虑两个选项 - 是否有办法获取地址信息:
-
通过模块初始化代码中的 printk()
通过内核代码中某处的 printk()
所有这些都在调用mod->init()
之前 - 所以我可以在那里放置一个断点,加载符号文件,点击 c 并看到它崩溃并烧毁......
【问题讨论】:
【参考方案1】:您可以将代码构建到内核中而不是作为模块吗?这可能会简化init()
调用的调试。
您还可以在do_one_initcall()
处设置断点并查看mod->init
的地址以获取加载地址。
【讨论】:
将代码编译到内核中太麻烦了(每次都需要刷写开发板而不是 wget 到 ramdisk)。闯入do_one_initcall()
足以确定问题所在,以便我可以推迟崩溃,直到启动与模块通信的用户模式进程。谢谢。以上是关于如何调试 Linux 内核模块 `init()` 中的问题?的主要内容,如果未能解决你的问题,请参考以下文章
Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动