内核调试(三)
内核调试配置选项
在编译的时候,为了方便调试和测试代码,内核提供了许多配置选项。这些选项都在内核配
置编辑器的内核开发菜单项(Kernel hacking menu )中,它们都依赖于CONFIG_DEBUG_KERNEL。当你开发内核的时候,作为一种练习,不妨打开所有这些选项。
有些选项确实有用,你应该启用(slab layer debugging) slab层调试选项,(high-memory debugging)高端内存调试选项,(I/O mapping debugging)I/O映射调试选项,(spin-lock debugging)自旋锁调试选项和(stack-overflow checking)栈溢出检查选项。其中最有用的一个是自旋锁内睡眠(sleep-inside-spinlock checking)选项,它确实能完成不少调试工作。
调试原子操作
从2.5版开始,为了检查各类由原子操作引发的问题,内核提供了极佳的工具。回忆一下原子操作指那些能够不分隔执行的东西;在执行时不会被中断否则就不完成的代码。正在使用一个自旋锁或禁止抢占的代码进行的就是原子操作。在进行此类操作的时候,代码不能睡眠——使用锁时睡眠是引发死锁的元凶。
托内核抢占的福,内核提供了一个原子操作计数器。它可以被配置成一旦在原子操作过程中进程进入睡眠或者做了一些可能引起睡眠的操作,就打印警告信息并提供追踪线索。所以,包括正使用锁的时候调用schedule(),正使用锁的时候以阻塞方式请求分配内存和在引用单CPU数据时睡眠在内,各种潜在的bug都能够被探测到。
下面这些选项可以最大限度的利用该特性:
CONFIG_PREEMPT=y
CONFIG_DEBUG_KERNEL=y
CONFIG_KALLSYMS=y
CONFIG_SPINLOCK_SLEEP=y
引发bug并打印信息
一些内核调用可以用来方便标记bug,提供断言并输出信息。最长用的两个是BUG()和BUG_ON()。当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印。为什么这些声明会导致oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_ON()定义成某种非法操作,这样自然会产生需要的oops。你可以把这些调用当作断言使用,想要断言某种情况不该发生:
if (bad_thing)
BUG();
或者使用更好的形式:
BUG_ON(bad_thing);
可以用panic()引发更严重的错误。调用panic()不但会打印错误消息而且还会挂起整个系统。显然,你只应该在极端恶劣的情况下使用它:
if (terrible_thing)
panic(“foo is %ld\n”, foo);
有些时候,你只是需要在终端上打印一下栈的回溯信息来帮助你测试。此时可以使用dump_stack()。它只在终端上打印寄存器上下文和函数的跟踪线索:
if (!debug_check) {
printk(KERN_DEBUG “provide some information…\n”);
dump_stack();
}
神奇的系统请求键
神奇系统请求键是另外一根救命稻草,该功能可以通过定义CONFIG_MAGIC_SYSRQ配置选项来启用。SysRq(系统请求)键都是键盘上的标准键。在i386和PPC上,它可以通过ALT-PrintScreen访问。当该功能被启用的时候,无论内核处于什么状态,你都可以通过特殊的组合键跟内核进行通信。这种功能可以让你面对一台奄奄一息的系统时能完成一些有用的工作。
除了配置选项以外,还要通过一个sysctl用来标记该特性的开或关。
需要启用它:
echo 1 > /proc/sys/kernel/sysrq
从终端上,你可以键入Sysrq-h获取一份可用的选项列表。SysRq –s将“脏”缓冲区跟硬盘交换分区同步,SysRq –u卸载所有的文件系统,SysRq –b重启设备。在一行内里发送这三个键的组合可以重新启动濒临死亡的系统,这比直接按下机器的reset键要安全一些。
如果机器已经完全锁死了,它也可能不会再响应神奇系统请求键,或者无法完成给定的命令。不过如果运气稍好的话,这些选项或许可以保存你的数据或者帮你进行调试。表2列举了所有支持的系统请求命令。
Table 2 支持SysRq 的命令
主要命令 描述
SysRq-b 重新启动机器
SysRq-e 向init以外的所有进程发送SIGTERM信号
SysRq-h 在控制台显示SysRq
SysRq-i 向init以外的所有进程发送SIGKILL信号
SysRq-k 安全访问键:杀死这个控制台上的所有程序
SysRq-l 向包括init的所有进程发送SIGTKILL信号
SysRq-m 把内存信息输出到控制台
SysRq-o 关闭机器
SysRq-p 把寄存器的信息输出到控制台
SysRq-r 关闭键盘原始模式
SysRq-s 把所有已安装文件系统都刷新到磁盘
SysRq-t 把任务信息输出到控制台
SysRq-u 卸载所有已安装文件系统
内核代码树中文件Deoumentation/sysrq.txt有此方面的更详细的信息。实际的实现在drivers/char/sysrq.txt中。神奇系统请求健是调试和挽救垂危系统所必需的一种工具。由于该功能对终端上的任何用户都提供服务,所以在重要的机器上启用它你需要三思而行。可是对于你自己用于开发的机器,启用它确实帮助很大。
[ 本帖最后由 陈莉君 于 2008-5-12 13:28 编辑 ]