统信UOS设备驱动开发-调试优化
包含linux设备驱动开发的基础知识及统信UOS设备驱动的总体架构,常用的设备驱动开发调试优化手段及在环境搭建和代码编写过程中常见问题处理等。
文章目录
- 一、驱动开发调试
- 调试信息打印
- debugfs
- 二、KGDB使用
- KGDB 配置
- 三、bpftrace
- 安装
- 语言规则
- 单行例程
一、驱动开发调试
调试信息打印
printk
驱动开发中,往往需要借助调试信息明确函数执行流程或者观测关键数据,此时我们可以使用内核提供的printk()接口输出信息到到内存环形缓冲区、终端、串口,由于printk()接口可用于中断上下文、进程上下文以及持有锁的情形而被内核开发者广泛使用。printk()接口定义如下:
asmlinkage __visible int printk(const char *fmt,…)
为区分不同的紧急程度,内核定义了0到7多个打印级别。如下所示,数字越大,相应的日志输出级别越低。
//include/linux/kern_levels.h5 #define KERN_SOH "\001" /* ASCII Start Of Header */ 6 #define KERN_SOH_ASCII '\001' 7 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 */
使用printk()输出时可指定输出级别,如下所示
printk(KERN_ERR "%s:%d hello uos\n",__func__,__LINE__);//以KERN_ERR级别输出 "函数名:行号 hello uos"printk(KERN_INFO "%s:%d hello uos\n",__func__,__LINE__);//以KERN_INFO级别输出 "函数名:行号 hello uos"
或者使用与printk(XXX)对应的pr_xxx()版本(推荐),如下所示
pr_err("%s:%d hello uos\n",__func__,__LINE__);//同printk(KERN_ERR "%s:%d hello uos\n",__func__,__LINE__);pr_info("%s:%d hello uos\n",__func__,__LINE__);//printk(KERN_INFO "%s:%d hello uos\n",__func__,__LINE__);...
或者使用与printk(XXX)对应的dev_xxx()版本(针对设备驱动开发者),如下所示。其中dev_xxx()为pr_xxx()的对应变体,此接口行为与pr_xxx()接口一直,但会额外输出"设备名称"、"主设备号"以及"次设备号“(如果存在)信息用于调试。
dev_err(dev,“%s:%d hello uos\n”,func,LINE);//以error级别输出 “函数名:行号 hello uos”;
dev_info(dev,“%s:%d hello uos\n”,func,LINE);//以error级别输出 “函数名:行号 hello uos”;
系统默认日志输出级别为4,即只输出以KERN_EMERG、KERN_ALERT、KERN_CRIT、KERN_ERR、KERN_WARNING级别打印