Linux动态调试无法显示变量值?驱动调试输出异常如何修复?
为何Linux动态调试无法显示变量值?
首先直接点出问题根源:你看到的动态调试条目里使用了_空标志,这个标志没有启用变量参数打印的功能,所以只会输出格式化字符串本身,不会替换%d这类占位符为实际变量值。
问题分析
从你提供的sys/kernel/debug/dynamic_debug/control内容来看:
drivers/misc/mei/hw-me.c:994 [mei_me]mei_me_d0i3_exit_sync =_ "d0i3 exit ret = %d\012"
这里的=_表示当前调试项的标志为空(_是默认的无标志占位符)。动态调试需要p标志来允许打印格式化字符串的变量参数,没有这个标志,内核只会输出字符串字面量,不会解析%d这类格式符对应的变量。
修复步骤
1. 先搞懂动态调试标志的含义
动态调试的控制条目格式为:file:line [module]function = flags "format string"
几个关键标志的作用:
p: 核心!启用格式化字符串的变量参数打印f: 在输出中包含函数名l: 在输出中包含行号m: 在输出中包含模块名t: 在输出中包含线程ID
2. 修改单个调试项的标志
用root权限执行echo命令,给目标条目添加p标志:
echo 'drivers/misc/mei/hw-me.c:994 [mei_me]mei_me_d0i3_exit_sync =p "d0i3 exit ret = %d\012"' > /sys/kernel/debug/dynamic_debug/control
如果想同时显示函数名、行号等额外信息,可以用组合标志,比如pfml:
echo 'drivers/misc/mei/hw-me.c:994 [mei_me]mei_me_d0i3_exit_sync =pfml "d0i3 exit ret = %d\012"' > /sys/kernel/debug/dynamic_debug/control
3. 批量修改整个模块的调试项
要是想给mei_me模块的所有动态调试项都加上变量打印功能,用批量命令更高效:
echo '+p module mei_me' > /sys/kernel/debug/dynamic_debug/control
这里+p表示给指定模块的所有调试项添加p标志;如果要移除标志,把+换成-即可。
4. 验证修复效果
触发对应驱动的调试场景(比如执行会调用mei_me_d0i3_exit_sync函数的操作),然后查看dmesg或者系统日志,应该能看到类似这样的输出:
[12345.678901] mei_me mei_me_d0i3_exit_sync: d0i3 exit ret = 0
而不是原来的d0i3 exit ret = %d。
注意事项
- 操作
/sys/kernel/debug/dynamic_debug/control必须有root权限。 - 确保内核编译时开启了
CONFIG_DYNAMIC_DEBUG配置项(你能看到control文件说明已经开启)。 - 调试标志的修改是临时的,重启系统后会恢复默认;如果需要永久生效,可以在启动脚本中添加对应的
echo命令,或者使用内核启动参数dyndbg="..."来预设标志。
内容的提问来源于stack exchange,提问作者Masoud




