对于任何一位内核代码的编写者来说,最急迫的问题之一就是如何完成调试。由于内核是一
个不与特定进程相关的功能集合,所以内核代码无法轻易地放在调试器中执行,而且也很难
跟踪。同样,要想复现内核代码中的错误也是相当困难的,因为这种错误可能导致整个系统
崩溃,这样也就破坏了可以用来跟踪它们的现场。
本章将介绍在这种令人痛苦的环境下监视内核代码并跟踪错误的技术。
4.1 通过打印调试
最普通的调试技术就是监视,即在应用程序编程中,在一些适当的地点调用 printf 显示监
视信息。调试内核代码的时候,则可以用 printk 来完成相同的工作。
4.1.1 printk
在前面的章节中,我们只是简单假设 printk 工作起来和 printf 很类似。现在则是介绍它
们之间一些不同点的时候了。
其中一个差别就是,通过附加不同日志级别(loglevel),或者说消息优先级,可让 printk
根据这些级别所标示的严重程度,对消息进行分类。一般采用宏来指示日志级别,例如,
KERN_INFO,我们在前面已经看到它被添加在一些打印语句的前面,它就是一个可以使用
的消息日志级别。日志级别宏展开为一个字符串,在编译时由预处理器将它和消息文本拼接
在一起;这也就是为什么下面的例子中优先级和格式字串间没有逗号的原因。下面有两个
printk 的例子,一个是调试信息,一个是临界信息:
printk(KERN_DEBUG "Here I am: %s:%i", _ _FILE_ _, _ _LINE_ _);
printk(KERN_CRIT "I'm trashed; giving up on %p", ptr);
在头文件 <linux/kernel.h> 中定义了 8 种可用的日志级别字符串。
KERN_EMERG
用于紧急事件消息,它们一般是系统崩溃之前提示的消息。
KERN_ALERT
用于需要立即采取动作的情况。
KERN_CRIT
临界状态,通常涉及严重的硬件或软件操作失败。
KERN_ERR
用于报告错误状态;设备驱动程序会经常使用 KERN_ERR 来报告来自硬件的问题。
KERN_WARNING
对可能出现问题的情况进行警告,这类情况通常不会对系统造成严重问题。
KERN_NOTICE
有必要进行提示的正常情形。许多与安全相关的状况用这个级别进行汇报。
KERN_INFO
提示性信息。很多驱动程序在启动的时候,以这个级别打印出它们找到的硬件信息。
评论0