linux内核printk调试手段,linux内核调试--printk()

本文解析了Linux内核中 printk 函数的日志级别控制机制,介绍了console_loglevel、default_message_loglevel、minimum_console_loglevel等概念,并展示了如何通过/proc/sys/kernel/printk文件调整打印级别。特别关注了NULL指针引发的oops错误及其调试方法。
摘要由CSDN通过智能技术生成

#define KERN_EMERG "<0>" /* system is unusable    */

#define KERN_ALERT "<1>" /* action must be taken immediately */

#define KERN_CRIT "<2>" /* critical conditions    */

#define KERN_ERR "<3>" /* error conditions    */

#define KERN_WARNING "<4>" /* warning conditions    */

#define KERN_NOTICE "<5>" /* normal but significant condition */

#define KERN_INFO "<6>" /* informational    */

#define KERN_DEBUG "<7>" /* debug-level messages    */

extern int console_printk[];

#define console_loglevel (console_printk[0])

#define default_message_loglevel (console_printk[1])

#define minimum_console_loglevel (console_printk[2])

#define default_console_loglevel (console_printk[3])

对于printk("……"),只有n小于console_loglevel时才能被打印。

假设default_message_loglevel的值等于4,如果printk的参数头没有 样式的字符,则在printk函数进一步处理前会加上<4>

minimum_console_loglevel是一个预设的值,平时不起作用,通过其他工具来设置console_loglevel的值,这个值不能小于minimum_console_loglevel的值

default_console_loglevel也是一个预设的值,平时不起作用,它别哦死设置console_loglevel时的默认值,通过其他工具设置console_loglevel的值时,会用到这个值

上面代码中的console_printk是一个数组,他在kernel/printk.c中定义

int console_printk[4] = {

DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */

DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */

MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */

DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */

};

在用户空间可以修改printk函数的记录级别

挂载proc文件系统后,读取/proc/sys/kernel/printk文件可以得到console_loglevel、

default_message_loglevel、minimum_console_loglevel、

default_console_loglevel 这四个值。

cat /proc/sys/kernel/printk

7 4 1 7

我们可以通过下列命令来修改这个值

echo "1 4 1 7" > /proc/sys/kernel/printk

这样可以设置答应终端的答应级别,只有当printk(……)中n小于console_loglevel时才能打印,如上吧

console_loglevel设置为1就只有打印级别为0的printk语句才能打印出来。由于新优先级可以指定为1~8之间的整数值,所以如果我们

要让所有的打印语句都能够答应出来的话我们可以

echo "8 4 1 7" > /proc/sys/kernel/printk

这样任何printk打印语句都能够打印信息。

还可以通过dmesg查看系统信息

oops消息

大部分错误都是因为对NULL指针取值或因为使用了其他不正确的指针值,这些错误通常会导致一个oops信息。

由于处理器使用的地址几乎都是虚拟地址,这些地址(除了内存管理子系统本身所使用的物理内存外)通过一个复杂的被称为页表的结构映射为物理地址,当引用一

个非法指针时,分页机制无法将该地址映射为物理地址,此时处理器就会想操作系统发出一个信号,而这时处理器恰好处于超级用户模式,系统就会产生一个

oops

oops显示出错时处理器的状态,比如cpu寄存器的内容以及其他看上去无法理解的信息。这些信息有printk打印出来

下面使用各使用NULL指针而导致oops的例子

Unable to handle kernel NULL pointer dereference at virtual address 00000000

pgd = c0004000

[00000000] *pgd=00000000

Internal error: Oops: 805 [#1]

Modules linked in:

CPU: 0    Not tainted (2.6.22.6 #18)

PC is at s3c2410fb_probe+0x18/0x560

LR is at platform_drv_probe+0x20/0x24

pc : []    lr : []    psr: a0000013

sp : c042fe64 ip : c042fea0 fp : c042fe9c

r10: 00000000 r9 : c0025864 r8 : c03892ec

r7 : 00000000 r6 : c0353358 r5 : 00000000 r4 : c032c560

r3 : 00001234 r2 : 00000001 r1 : c047bd84 r0 : c032c558

Unable to handle kernel NULL pointer dereference at virtual address 00000000

可以看出使用了空指针。找出函数调用关系:PC is at s3c2410fb_probe+0x18/0x560

,表示出错指令为 s3c2410fb_probe函数中偏移为0X18的指令。pc : [] 表示出错指令的地址为c001abc4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值