嵌入式(驱动-基础):22---调试技术之(printk工作原理、缓冲区__LOG_BUF_LEN、klogd、syslogd、/proc/kmsg)
分类:
文章
•
2024-11-09 20:36:16
一、printk工作原理
- printk函数会将消息写入一个长度为__LOG_BUF_LEN字节循环缓冲区中。然后,会唤醒任何正在等待消息的进程,例如睡眠在syslog系统调用上的进程,或者正在读取/proc/kmsg的进程,这两个访问日志引擎的接口几乎是等价的,它们都会读取内核日志缓冲区的内容
-
不同点:
- ①对/proc/kmsg进行操作时来读取缓冲区中的日志消息,日志缓冲区中被读取的数据就不再保存了
- ②而syslog系统调用却能通过选项返回日志数据并保留这些数据,以便其他进程也能使用
klogd与syslogd的工作原理

- klogd运行时会读取内核消息并将它们分发到syslogd,syslogd随后查看/etc/syslog.conf文件找出处理这些数据的方法
- syslogd根据功能和优先级对消息进行分区,功能和优先级消息的取值军定义在<sys/syslog.h>中
-
内核消息有LOG_KERN工具记录,并以与printk中对应的优先级记录(例如,printk中使用的KERN_ERR对应于syslogd中的LOG_ERR)
-
如果没有运行klogd,数据将保留在循环缓冲区中,直到某个进程读取它们或缓冲区溢出为止
-
日志消息转移:如果想避免因为来自驱动程序的大量监视消息而干扰系统日志,那么可以使用下面的方式来将消息传送到别处:
- ①可以为klogd指定-f选项,指示其将消息保存到某个特定的文件
- ②修改/etc/syslog/conf来满足自己的需求
- ③强制杀死klogd进程,那么消息将打印到空闲的虚拟终端上
- ④在一个未使用xterm上执行命令cat /proc/kmsg来显示消息
- 一般来说,读/proc文件要容易些,这也是klogd的默认方法
- dmesg命令可在不刷新缓冲区的情况下获得缓冲区的内容,实际上,该命令将缓冲区的整个内容返回到stdout,而无论该缓冲区是否已经被读取
- 如果在停止klogd之后手动读取内核消息,读者会发现/proc/kmsg文件很像一个FIFO,读取进程会阻塞在该文件上,以便等待更多的数据。显然,如果已经有klogd或其他进程正在读取同一数据,就不能采用这种方法读取消息,因为会与其他进程发生竞争
二、printk缓冲区(__LOG_BUF_LEN)
- printk函数将消息写到一个长度为__LOG_BUF_LEN字节循环缓冲区中(我们可以在配置内核时为__LOG_BUF_LEN指定为4KB~1MB之间的值)
-
如果缓冲区满了:如果缓冲区满了,printk就绕回缓冲区的开始处填写新的数据,因此会覆盖最初的旧的数据,此时会造成数据的丢失。但是这个问题可以忽略不计,例如,循环缓冲区可以使系统在没有记录进程的情况下照样运行,同时覆盖那些不会再去有人读取的旧数据,从而减少了内存的浪费
- printk的另一个特点就是,可以在任何地方调用printk,甚至在中断处理函数中也可以,而且对数据量的大小没有限制,而这个方法的唯一缺点就是可能丢失某些数据(源于循环缓冲区的缘故)