前言
复习一下Linux内核开发使用的调试手段,主要包含如下方法:
- printk及pr_xxx
- 动态输出
- procfs文件系统
- sysfs文件系统
- debugfs文件系统
printk
printk是最常用的调试方法,可以在代码中加入一些打印信息,了解内核模块执行的情况。类似于printf,不过printk是区分了打印等级的,可以通过配置让内核打印相应的等级日志。
printk提供8个打印等级,分别为 DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGE,等级越来越高,对应7-0,值越小等级越高。
内核编译配置可以通过CONFIG_MESSAGE_LOGLEVEL_DEFAULT设置默认打印等级,默认是4(WARNING)。
还可以通过系统启动参数配置打印等级 loglevel=8, 也可以在启动后动态修改等级,修改 /proc/sys/kernel/printk的值。
1 | root@keep-Inspiron-3020-S:/home/keep/code/raw_blog# cat /proc/sys/kernel/printk |
pr_xxx是对printk的一个包装,printk是基础的接口,而pr_xxx可以通过名称体现出等级。
还有2个常用的打印接口
- print_hex_dump 打印内存数据
- dump_stack 打印调用栈
动态输出
内核配置CONFIG_DYNAMIC_DEBUG配置使能动态输出功能,可以在内核运行时动态配置信息的输出,而printk属于全局的静态配置。
使用动态输出需要在代码中使用pr_debug/dev_dbg函数打印信息。
1 | 查看内核动态输出代码分布情况 |
proc和sys文件系统
proc系统提供了一种内核和内核模块向用户态发送消息的机制。这个虚拟文件系统主要提供内核内部的数据结构信息,也可以用来查看系统的信息。
1 | 查看系统启动的参数 |
proc文件系统主要用于显示系统相关的信息,对于一般模块而言,则使用sys文件系统,提供了一套统一的设备驱动模型。
现在很多模块都是用sys作为与用户空间的友好接口,比如uio模块。系统默认创建的字符设备等,也会在sys下创建对应的文件。
1 | /dev/kvm有对应的目录 |
debugfs文件系统
debugfs则是一个纯粹用来调试内核的文件系统, 而proc和sys则是作为用户接口来使用的,不适合暴露私有的调试信息。最基础的内核调试是打印日志,但是如果涉及到数据修改的,就可以使用debugfs文件系统了,否则只能修改代码重新编译加载。
debugfs 一般挂在到/sys/kernel/debug目录下,比如dma模块就有相关的文件在该目录下。之前看的dma-api使用接口,当开启了CONFIG_DMA_API_DEBUG就会在/sys/kernel/debug目录下创建一个dma-api的目录。
1 | root@keep-Inspiron-3020-S:~# ls /sys/kernel/debug/dma-api/ |
类似proc和sys, debugfs也提供了api来读写文件的接口来实现数据通信,用于调试。
本文相关测试代码: https://gitee.com/fishmwei/blog_code/blob/master/linux-kernel/dbgm/dbgm.c
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。
博客地址: https://fishmwei.github.io
掘金主页: https://juejin.cn/user/2084329776486919