您的位置:首页 > 运维架构 > Linux

linux内核调试

2013-11-14 13:48 316 查看
#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>"……"),只有n小于console_loglevel时才能被打印。

假设default_message_loglevel的值等于4,如果printk的参数头没有 <n> 样式的字符,则在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>……)中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 : [<c001abc4>] lr : [<c0185f28>] 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>] 表示出错指令的地址为c001abc4

#Linux
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: