Linux内核调试利器——printk
来源:互联网 发布:双色球参选数据 编辑:程序博客网 时间:2024/05/16 16:11
在Linux开发环境下,打印log一直是最有效的调试方式,内核开发也不例外。
先看一下下面这段代码:
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("Wang Shuxiao");static int hello_init(void){ printk(KERN_INFO "hello, linux kernel"); return 0;}static void hello_exit(void){ printk(KERN_INFO "Goodbye, linux kernel");}module_init(hello_init);module_exit(hello_exit);
将其编译成hello.ko模块,反复insmod/rmmod之后发现,我在insmod的时候,它打印出”Goodbye, linux kernel”;而在rmmod时,它打印出”hello, linux kernel”,奇了个怪!
bookxiao@ubuntu-kernel:~$ tail -f /var/log/messagesSep 28 10:12:47 ubuntu-kernel kernel: [ 742.327807] Goodbye, linux kernelSep 28 10:14:05 ubuntu-kernel kernel: [ 838.865803] hello, linux kernel
后来,在Linux Device Driver 里面看到这么一句话:
Based on the loglevel, the kernel may print the message to the current console, be it a text-mode terminal, a serial port, or a parallel printer. If the priority is less than the integer variable console_loglevel, the message is delivered to the console one line at a time (nothing is sent unless a trailing newline is provided).
原来是printk里面未在末尾添加换行符,导致不能及时flush到终端。修复后即正常。
下面是内核日志系统的基本框架和使用方法。
这是一个典型的生产者-消费者模型。
- printk将消息写入一个循环buffer,大小在编译内核时(CONFIG_LOG_BUF_SHIFT)指定。当buffer满时,会覆盖掉开始处的(最老的)的消息。ring buffer的设计可以使读写操作无需同步:读操作总是发生在队列头,写操作总是发生在队列尾。因此,可以在任何上下文中调用printk:可以在进程上下文中调用,也可以在中断上下文中调用,甚至在持有锁的情况下调用。
- 消费者通过syslog()系统调用或者直接读”/proc/kmsg”文件,即可从ring buffer读取数据,若无数据可读,则会阻塞。klogd进程采用的就是第二种方法,将内核消息读出来,并发送到syslogd进程。
- 此外,printk会判断消息级别和系统当前console_loglevel的值,如果消息级别高于console loglevel,会将消息同时输出到控制终端。
注意,上面的syslog()指的是系统调用,而非glibc(用户空间)的syslog()。这两个的作用是不同的:内核里的syslog作为消费者,从ring buffer读取数据(定义在linux-source/kernel/printk.c中的);用户空间的syslog()则是一个工具,可以向syslogd(或rsyslogd)进程写入数据,syslogd再将数据dispatch到不同的文件(根据/etc/syslog.conf)。默认情况下,从klogd发送过来的内核消息,会被写入到/var/log/messages文件。
/* kernel/printk.c */SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len){ return do_syslog(type, buf, len, SYSLOG_FROM_CALL);}
参考资料
[1] Linux kernel development, Robert Love
[2] Advanced Programming in UNIX Environment, 3rd
[3] Linux Device Driver, 3rd
- Linux内核调试利器——printk
- linux内核printk调试
- linux内核printk调试
- linux内核printk调试
- Linux内核调试printk()总结
- Linux 内核调试之 printk
- linux内核调试中的printk()函数详解
- linux内核调试技术之printk
- linux内核调试技巧一:printk
- printk内核调试
- 内核调试函数printk()
- Linux设备驱动程序——驱动调试printk()
- linux设备驱动学习笔记--内核调试方法之printk
- linux内核打印--printk
- Linux内核printk实现
- linux内核之printk
- LINUx 驱动程序printk 调试
- printk 内核调试 消息级别
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- free函数陷进
- AssetBundle系列——共享资源打包/依赖资源打包
- JSP动作元素jsp:useBean,jsp:setProperty,jsp:getProperty
- WIN7 下安装MAVEN
- Linux内核调试利器——printk
- HDU 5491 The Next (2015年合肥赛区网络赛H题)
- 深度学习(五)caffe环境搭建
- 怎样解决MathType中希腊字母无法显示问题
- Android项目Tab类型主界面大总结
- 软工视频总结(后期)
- javabean简介
- RTEMS4.11 FEDORA20 64BIT环境搭建
- kafka多线程消费