Linux 内核的动态调试
一、背景
调试android 内核的可能清楚,对于一些概率性的问题,能够正确抓到日志是有多么重要。但是,为了不影响用户的正常使用,保证良好的使用性能,log必须控制在一定的量。但是对于一些涉及到协议相关的,为了方便调试,又必须加入一些打印数据的日志。这个时候,用户性能和调试需求产生了冲突。
如何解决这个问题呢?其实linux 已经考虑到这些问题。
- linux 引入log调试的概念
linux内核引入了log等级这一概念,linux log等级分为8个等级,分别从0 - 7等级,详细请参考内核代码:kern_levels.h
8 #define KERN_EMERG KERN_SOH "0" /* system is unusable */
9 #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
10 #define KERN_CRIT KERN_SOH "2" /* critical conditions */
11 #define KERN_ERR KERN_SOH "3" /* error conditions */
12 #define KERN_WARNING KERN_SOH "4" /* warning conditions */
13 #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
14 #define KERN_INFO KERN_SOH "6" /* informational */
15 #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
- linux 引入log的动态打印概念
以高通平台为例,使用如下指令,挂载debugfs文件系统
mount -t debugfs /debugfs /sys/kernel/debug
看出自己的文件是否支持动态调试
cat /sys/kernel/debug/dynamic_debug/control
如何动态打印
1) 打印一个文件中的所有动态打印语句,以gadget.c为例
echo -n "file gadget.c +p" > /sys/kernel/debug/dynamic_debug/control
。
2) 打印一个模块中所有动态打印语句
echo -n "module dwc3 +p" > /sys/kernel/debug/dynamic_debug/control
3 打开一个函数中所有动态打印语句
echo -n "func port_event +p" > /sys/kernel/debug/dynamic_debug/control
- 打开文件路径中包含usb的文件里所有的动态打印语句
echo -n "*usb* +p" > /sys/kernel/debug/dynamic_debug/control
需要根据自己的需要,开启日志等级。
两种方式
- 使用命令开启log等级
dmesg -n 8 - 直接echo 设置
echo 7 > /proc/sys/kernel/printk
最后一点需要主要,这里的打印都是动态打印语句。什么是动态打印语句?
1.定义在内核代码头文件中include/linux/device.h
#define dev_dbg(dev, fmt, ...) \
dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
- 开启动态调试,需要开启宏CONFIG_DYNAMIC_DEBUG