printk

在编写应用程序时,我们可以通过printf打印输出一些信息用来调试程序,Linux内核也提供了类似的函数printk,和printf不同的是,printk提供了输出日志级别,日志级别有:
KERN_EMERG
KERN_ALERT
KERN_CRIT
KERN_ERR
KERN_WARNING
KERN_NOTICE
KERN_INFO
KERN_DEBUG
KERN_EMERG级别最高,KERN_DEBUG最低,如果printk没有指定输出日志级别,则采用默认的日志级别,默认值为DEFAULT_MESSAGE_LOGLEVEL,在Linux-2.6.32中被指定为4,即KERN_WARNING。

既然printk有个输出日志级别,那么什么样的日志信息能够输出呢?内核是通过变量console_loglevel来判断的,printk指定的日志级别小于console_loglevel值的日志信息才能够输出,console_loglevel初始值为DEFAULT_CONSOLE_LOGLEVEL,在Linux-2.6.32平台下值为7,也就是说除了KERN_DEBUG级别外,其它级别的日志信息都能够输出,另外console_loglevel是可以通过系统调用syslog去设置的,也可以通过make menuconfig在kernel hacking选项中去配置这个值。

在开发驱动程序初期阶段,可能需要使用printk用来调试驱动程序,但是在程序发布时,就得删除这些打印语句,这里提供一种方法,就是通过宏定义来启用或禁止打印信息:
#define DEBUG

#ifdef DEBUG
#define MYDEBUG(fmt, args...) printk(KERN_DEBUG fmt, ##args)
#else
#define MYDEBUG(fmt, args...)

#endif


// 2015.09.01 add
使用printk固然可以正确的打印出调试信息,但是在CodingStyle中说了对于具体同device相关的调试信息应该使用dev_err()、dev_warn()、dev_info()宏,这些宏定义在<linux/device.h>中,这些宏不仅同具体的设备相关联,并且正确标记了消息级别。而如果不同某个设备相关联的话,应该使用pr_err()、pr_debug()、pr_info()等宏,定义在<linux/printk.h>中。


// 2015.09.14 add

动态debug

所谓动态debug就是我们可以手动的enable、disable掉一些打印信息,要使用动态debug,那么CONFIG_DYNAMIC_DEBUG这个宏必须被设置,另外并不是所有的打印语句都支持动态debug的,只针对向dev_dbg、pr_debug这类宏。

动态debug这里还会涉及到一个debugfs,在android中debugfs通常是挂载到/sys/kernel/debug目录的。

那么接下来看我们如何enable、disable掉打印信息的(dynamic-debug-howto.txt)。

Examples
========

// enable the message at line 1603 of file svcsock.c
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
				<debugfs>/dynamic_debug/control
// enable svcsock.c文件中的1603行打印

// enable all the messages in file svcsock.c
nullarbor:~ # echo -n 'file svcsock.c +p' >
				<debugfs>/dynamic_debug/control
// enable svcsock.c文件中的所有打印

// enable all the messages in the NFS server module
nullarbor:~ # echo -n 'module nfsd +p' >
				<debugfs>/dynamic_debug/control
// enable nfsd模块的所有打印

// enable all 12 messages in the function svc_process()
nullarbor:~ # echo -n 'func svc_process +p' >
				<debugfs>/dynamic_debug/control
// enable svc_process函数中的打印

// disable all 12 messages in the function svc_process()
nullarbor:~ # echo -n 'func svc_process -p' >
				<debugfs>/dynamic_debug/control
// disable svc_process函数中的打印

// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
				<debugfs>/dynamic_debug/control

// enable messages in files of which the paths include string "usb"
nullarbor:~ # echo -n '*usb* +p' > <debugfs>/dynamic_debug/control

// enable all messages
nullarbor:~ # echo -n '+p' > <debugfs>/dynamic_debug/control

// add module, function to all enabled messages
nullarbor:~ # echo -n '+mf' > <debugfs>/dynamic_debug/control

// boot-args example, with newlines and comments for readability
Kernel command line: ...
  // see whats going on in dyndbg=value processing
  dynamic_debug.verbose=1
  // enable pr_debugs in 2 builtins, #cmt is stripped
  dyndbg="module params +p #cmt ; module sys +p"
  // enable pr_debugs in 2 functions in a module loaded later
  pc87360.dyndbg="func pc87360_init_device +p; func pc87360_find +p"

你可能感兴趣的:(printk)