linux内核调试之kmsg和dmesg

1.linux中系统信息打印原理

1.1 ring buffer(‘log_buf’)

   在LINUX中,所有的系统信息(包内核信息)都会传送到ring buffer(‘log_buf’)中.而内核产生的信息由printk()打印出来,系统启动时所看到的信息都是由该函数打印到屏幕中或者串口等其他地方。 printk()打出的信息往往以 <0>…<2>… 这的数字表明消息的重要级别。高于一定的优先级别会打印到屏幕上,否则只会保留在系统的缓冲区中(ring buffer).。

1.2 查看系统信息放置的位置

  LINUX系统启动后,由/etc/init.d/sysklogd先后启动klogd,syslogd两个守护进程。其中klogd会通过syslog()系统调用或者读取proc文件系统来从系统缓冲区(ring buffer)中得到由内核printk()发出的信息.而syslogd是通过klogd来读取系统内核信息(klogd将读到的东西发给syslogd).Klogd和syslogd都是用户空间进程。Klogd的输出结果会传送给syslogd进行处理,syslogd会根据/etc/syslog.conf()(ubuntu的/etc/syslog.conf不再有!而是/etc/rsyslog.conf代替!)的配置把log信息输出到/var/log/下的不同文件中

dmesg日志在哪看_dmesg日志在哪看


由图中配置可以看到,系统信息在var/log/kern.log中

#查看所有的系统信息
vi /var/log/kern.log

2.dmesg

  dmesg是从kernel的ring buffer(环缓冲区)中读取信息的,可以用dmesg 来显示ring buffer内容,还可以用dmesg >xxx.txt 把ring buffer的内容保存为文件,但是如果ring buffer有可能刷新了或者满了有些信息会漏掉,而且dmesg不能实时打印系统发生了什么,这个时候就需要kmsg。

  • dmesg -w可以实时查看日志信息
  • dmesg -w >log.txt 可以把实时的打印放到log.txt中
  • dmesg -C 可以清除ringbuf的内容

3.kmsg

  /proc/kmsg是专门输出内核信息的地方,为了能够方便的在 user space 读取 Kernel log,Kernel driver 里面将ring buffer映射到了 /proc 目录下的文件节点 /proc/kmsg。所以读取 /proc/kmsg 文件其实就是在访问 Kernel Log 的循环缓冲区。虽然 Log buffe的大小是固定的,但是可以通过不断的访问 /proc/kmsg 将所有的log都备份下来。

#实时显示内核打印信息,它会block住,然后随着调试不断打印。当有printk打印出信息的时候,自然会在窗口中打印出来的,他只打印最新的打印。
sudo cat /proc/kmsg
#重定向将 Log 转存到文件中
sudo cat /proc/kmsg >~/Desktop/a.txt

使用限制
由于 Kernel log buffer 循环缓冲区只有一个读指针,所以当一个程序在读 buffer 的时候会不断的移动 buffer 的读指针,这样当有多个程序读取 buffer 的时候每个程序得到的log都不是完整的。所以当访问 /proc/kmsg 的时候务必保证没有其它程序读取 Kernel Log Buffer。
/proc/kmsg 的 Owner 是 root,群组属于 System,所以在 user 版本上面是无法 读取 Kernel Log Buffer 的。