linux标准的打印函数是printk。
#define KERN_EMERG "<0>"
#define KERN_ALERT "<1>"
#define KERN_CRIT "<2>"
#define KERN_ERR "<3>"
#define KERN_WARNING "<4>"
#define KERN_NOTICE "<5>"
#define KERN_INFO "<6>"
#define KERN_DEBUG "<7>"
通过proc文件系统,可以动态调整printk的打印级别。
#cat /proc/sys/kernel/printk
4 4 1 7
分别是
current log level,当前打印级别,如果优先级高于此级别,就打印出去。通常设置为4.等于或者低于4级,不会被打印。
default log level,默认的printk的打印级别,如果调用printk时,没有指定消息前导字符串,那么就添加默认的等级前导字符串。通常设置为4.
min log level value,可以被设置的最小值,一般为1。
default console log level,默认的console log的打印级别,如果没有通过proc文件系统修改打印级别,那么默认的打印级别就从这个参数项中提取。通常设置为7。
#echo 8 > /proc/sys/kernel/printk
将使得current log level 被设置为8 ,即,高于8的消息都可以被打印,DEBUG是7,所以这时候可以被打印出来。
在驱动开发时,通常使用了封装了printk的宏。
#define dev_printk(level, dev, format, arg...) \
printk(level "%s %s:" format, dev_driver_string(dev), (dev)->bus_id, ##arg)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG, dev, format, ##arg)
#define dev_err(dev, format, arg...) \
dev_printk(KERN_ERR, dev, format, ##arg)
#define dev_info(dev, format, arg...) \
dev_printk(KERN_INFO, dev, format, ##arg)
#define dev_warn(dev, format, arg...) \
dev_printk(KERN_WARNING, dev, format, ##arg)
#define dev_notice(dev, format, arg...) \
dev_printk(KERN_NOTICE, dev, format, ##arg)
printk不是直接向console发送数据,而是把数据先写入buffer。等到console被初始化之后,再发送给console。
所以,通常要选择earlyprintk。然后在bootargs中添加earlyprintk参数项。
oops消息,是确定错误的可能原因的重要依据。
oops消息,是机器指令,所以需要转换成更友好的形式。
ksymoops工具用来完成这个工作。
#ksysoops -m System.map < myoops.txt
这个命令将oops信息转换成人类语言格式,并将处理结果输出重定向到txt文件中。
当然,在开发阶段,也可以选择kallsyms选项,让内核可以追溯函数名称,不再打印机器码。但是代价是,符号表被编译到内核中,而且常驻内存。
strace是一个有效的跟踪工具,用来监控Process中调用的SYSCALL。
将strace绑定到一个PID上,就可以监控这个process的SYSCALL行为。
输出的结果,是一系列字符串行,
等式左边表示执行的语句,等式右边表示SYSCALL的返回值。