用于内核测试的内核模块

背景 在调试内核时,最常用的方式就是添加打印。这个方法简单直接,但有个问题:若添加打印的函数会被频繁地调用执行,那这很可能使系统在启动或运行阶段触发海量的打印,反而将关键的信息淹没;或者由此导致系统运行卡顿甚至无法启动。 还有另一种常见的调试需求:我们需要在内核中模拟某种故障,并且是以我们所能掌控的时机和方式来触发。关于这点我们一般会想到内核故障注入,但其手段和所涉及的软件工具比较复杂,且其所能模拟的故障种类和故障位置一般是给定的,无法随意调整。 对于上述两个场景,我们其实可以用同一个方法解决:在内核中预埋一个“开关”,并在内核的用户态接口(如 proc 文件系统)上创建一个专门的接口来控制这个开关。对于第一个场景,我们可以将那些打 …

Linux 内核问题调试手段

源代码定位方法 我们经常需要根据内核错误日志,在源代码中比较精确地定位到发生错误的那一行。一般而言,我们通过错误发生的地址来定位对应的源代码:(链接 ) 1# 注意:这里的 vmlinux 需要带有调试信息 2addr2line -f -e vmlinux <asm_addr> 然而在内核错误日志中,调用栈常以形如 bdi_register+0xec/0x150 的形式1展示函数调用地址,而 addr2line 无法解读这样的格式。此时我们可以使用 GDB 来解析该地址: 1# In `gdb vmlinux`, compiled with CONFIG_DEBUG_INFO=y 2 3list …

Linux 内核问题调试手段——QEMU 专题

VM 启动后没有输出?莫慌~ 一般而言,在运行 qemu-system-xxx 启动虚拟机后,我们希望在主机的当前终端上看到内核的启动日志,并在虚拟机启动后用该终端直接操作虚拟机。然而有时,当前终端在运行了 qemu-system-xxx 后却毫无动静。此时,在确认内核可以正常启动的前提下,要去确认几件事情: 当前终端对 QEMU 虚拟机而言是什么设备; 当前内核使用的 /dev/console 指向了哪个设备。 先找到一个可用的虚拟机终端(比如通过 VNC 连接的方式),然后向 /dev/{console,tty{,S}{0,1,...}} 等物理终端设备文件逐个尝试输入一些内容,看看哪个文件能让主机的当前终端有输出1。确定了是哪 …