Linux内核中部分调试打印默认自动启用的原因探究
Linux内核dynamic debug默认启用部分打印的原因解析
测试环境与背景
我正在探索Linux内核的dynamic debug特性,使用5.16主线内核在QEMU上运行,启动命令如下:
qemu-system-aarch64 -smp 4 -m 2G -machine virt -cpu cortex-a57 -kernel uImage \ -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01 \ -display none -serial mon:stdio \ -append "console=ttyAMA0,115200n8 root=/dev/nfs rw nfsroot=10.105.226.234:/home/naveen/nfsroot/rootfs-busybox-arm64,nolock,vers=4,tcp ip=10.105.226.235"
根文件系统采用Busybox,未添加任何启用dynamic debug的命令行参数,且这些默认启用的打印来自内核内置功能(非加载模块)。
现象说明
查看/proc/dynamic_debug/control后发现,有37条调试打印默认处于启用状态(标记为=p),示例如下:
$ cat /proc/dynamic_debug/control | grep =p drivers/scsi/libsas/sas_expander.c:2084 [libsas]sas_rediscover =p "ex %016llx phy%02d originated BROADCAST(CHANGE)\012" drivers/scsi/libsas/sas_expander.c:2008 [libsas]sas_rediscover_dev =p "ex %016llx rediscovering phy%02d%s\012" drivers/scsi/libsas/sas_expander.c:2048 [libsas]sas_rediscover_dev =p "ex %016llx phy%02d broadcast flutter%s\012" drivers/scsi/libsas/sas_scsi_host.c:117 [libsas]sas_scsi_task_done =p "task done but aborted\012" drivers/scsi/libsas/sas_scsi_host.c:122 [libsas]sas_scsi_task_done =p "task_done called with non existing SCSI cmnd!\012" drivers/scsi/libsas/sas_queuecommand =p "lldd_execute_task returned: %d\012"
未启用的打印共有5513条(标记为=_):
$ cat /proc/dynamic_debug/control | grep =p | wc -l 37 $ cat /proc/dynamic_debug/control | grep =_ | wc -l 5513
原因分析
这些默认启用的dynamic debug打印,是内核代码编写阶段就预先设定的行为,核心原因包括:
- 代码层面的显式配置:部分驱动或子系统的开发者会将关键的、低输出量的调试信息设置为默认开启,比如你看到的libsas子系统打印,多是错误处理、状态变更类的关键信息,不会在正常流程中频繁输出,能在出现基础问题时快速排查。
- 调试宏的属性设定:内核中
pr_debug()、dev_dbg()这类宏支持附加默认启用属性,开发者在定义调试打印时,可通过特定标记让其在dynamic debug初始化时自动处于激活状态(即=p)。 - 编译与初始化逻辑:当内核开启
CONFIG_DYNAMIC_DEBUG选项后,dynamic debug子系统启动时会遍历所有注册的调试项,对代码中标记为默认启用的条目自动设置打印权限,无需额外命令行参数触发。
本质上这是内核开发者的设计选择,平衡了调试可用性与系统性能,既保留关键信息的默认可见性,又避免大量非必要打印占用资源。
内容的提问来源于stack exchange,提问作者InsaneCoder
相关产品推荐
相关产品推荐

