分类: 嵌入式
2012-08-26 15:10:01
http://blog.csdn.net/flykite1988/article/details/6122433
1 printk
[1] 使用范围
除在系统启动过程中 , 终端未初始化之前 , 其他任何时候 , 任何地方都可以调用它 .
[2] 记录等级
KERN_EMERG, KERN_ALERT, KERN_CRIT, KERN_ERR, KERN_WARNING, KERN_NOTICE, KERN_INFO, KERN_DEBUG.
若不指定记录等级 , 函数会�"淞� default_message_loglevel 指定的等级 , 该变量被初始化为 DEFAULT_MESSAGE_LOGLEVEL( 目前为 KERN_WARNING).
[3] 消息去向
按以下顺序进行 :
Step1 如果 klogd 和 syslod 都在运行 , 内核信息被追加到 /var/log/messages( 或者其他地方 , 依据 syslogd 的配置 ). 否则
Step2 依据变量 console_loglevel 的值来决定是否把内核消息打印到当前终端 (text-mode terminal, a serial port, or a parallel printer). 如果记录等级小于 console_loglevel 整数变量的值 , 则内核信息一次一行被发送到终端 .
*** 无论在 Step1 和 Step2 中都可以通过 dmesg 命令来查看 /proc/kmsg 中的内核信息 .
*** 只有在 console 下才有可在终端中打印出来 (ctrl+alt+F1…F6), 在 Gnone 或 KDE 下不可以 .
[4] 查看并修改重要变量的值
变量 |
初始值 |
查看当前值 |
修改方法 |
console_loglevel |
DEFAULT_CONSOLE_LOGLEVEL |
$ cat /proc/sys/kernel/printk First one |
(1) sys_syslog 系统调用 (2) 启动 klogd 时用 -c 选项来指定 console_loglevel 的值 (3) $ echo 8 > /proc/sys/kernel/printk |
default_message_loglevel |
DEFAULT_MESSAGE_LOGLEVEL |
$ cat /proc/sys/kernel/printk second one |
(1) $ echo 8 > /proc/sys/kernel/printk |
[5] 记录缓冲区
内核信息被保存在一个 LOG_BUF_LEN 大小的环形队列中 . 该缓冲区大小可以在编译时通过 CONFIG_LOG_BUF_SHIFT 进行调整 . 在单处理器的系统上其默认值为 16Kb.
[6] Linux 系统日志
syslogd 这个守护进程根据 /etc/syslog.conf, 将不同的服务产生的 Log 记录到不同的文件中 .
LINUX 系统启动后,由 /etc/init.d/sysklogd 先后启动 klogd,syslogd 两个守护进程。
其中 klogd 会通过 syslog() 系统调用或者读取 proc 文件系统来从系统缓冲区 (ring buffer) 中得到由内核 printk() 发出的信息 . 而 syslogd 是通过 klogd 来读取系统内核信息 .
1> 所有系统信息是输出到 ring buffer 中去的 .dmesg 所显示的内容也是从 ring buffer 中读取的 .
2> LINUX 系统中 /etc/init.d/sysklogd 会启动 2 个守护进程 :Klogd, Syslogd
3> klogd 是负责读取内核信息的 , 有 2 种方式 : syslog() 系统调用 ( 这个函数用法比较全 , 大家去 MAN 一下看看 ) 直接的对 /proc/kmsg 进行读取 ( 再这提一下 ,/proc/kmsg 是专门输出内核信息的地方 )
4> Klogd 的输出结果会传送给 syslogd 进行处理 ,syslogd 会根据 /etc/syslog.conf 的配置把 log 信息输出到 /var/log/ 下的不同文件中 .
2 OOPS
Oops 中包含的重要信息对于所有体系结构都是完全相同的 : 寄存器上下文和回溯线索 . 回溯线索显示了导致错误发生的函数调用链 . 寄存器上下文信息可能同样有用 , 尽管使用起来不那么方便 . 如果你有函数的汇编代码 , 这些寄存器数据可以帮助你重建引发问题的现场 . 在寄存器中一个本不应该出现的数值可能会在黑暗中给你带来第一丝光明 .
[1] ksymoops
提供编译内核是产生的 System.map 和模块信息 ( 如何你使用的是模块 ) 把 OOPS 信息解码 .
$ ksymoops saved_oops.txt
[2] kallsysms
开发版的 2.5 内核引入了 kallsysms 特性 , 它可以通过定义 CONFIG_KALLSYMS 配置选项启用 . 该选项可以载入内核镜像对应的内存地址的符号名称 , 所以内核可以打印解码好的跟踪线索 . 相应地 , 解码 oops 也不再需要 system.map 或者 ksysmoops 工具了 .
3 内核调试配置选
这些选项都在内核配置编辑器的内核开发 (Kernel Hacking) 菜单中 , 他们都依赖于 CONFIG_DEBUG_KERNEL. 当你开发内核的时候 , 作为一种练习 , 不妨都打开这些选项 .
[1] 调试原子操作
把内核配置成一旦在原子操作过程中进程进入休眠或者做了一些可能引起休眠的操作 , 就打印警告信息并提供追踪线索 .
CONFIG_PREEMPT = y
CONFIG_DEBUG_KERNEL = y
CONFIG_KALLSYMS = y
CONFIG_SPINLOCK_SLEEP = y
4 引发 bug 并打印信息
BUG() BUG_NO() 被调用时引发 oops, 导致栈的回溯和错误信息的打印
panic() 不但会打印错误信息 , 而且会挂起整个系统
dump_stack() 在终端上打印寄存器上下文和函数跟踪线索 .
5 神奇的 SysRq
神奇系统请求键是另外一根救命稻草 , 该功能可以通过定义 CONFIG_MAGIC_SYSRQ 配置选项开启用 . 当该功能被启用的时候 , 无论内核处于什么状态 , 你都可以通过特殊的组合键跟内核进行通信 .
6 内核调试器的传奇
[1] gdb
$ gdb vmlinux /proc/kcore
> p global_variable
> disassemble function
[2] kgdb
[3] kdb