2026/4/17 8:07:41
网站建设
项目流程
医院的 建设网站的策划书,网站建设拍金手指排名贰贰,南昌做公司网站哪家好,视频模板一键生成1. 前文回顾
Linux的Dynamic debug功能简单讲了下如何使用。再来回顾下其概念和用法。 Dynamic Debug 是 Linux 内核的动态调试功能#xff0c;允许在运行时动态开启/关闭特定的 pr_debug() 和 dev_dbg() 输出#xff0c;而无需重新编译内核。
核心特点#xff1a;
✅ 运…1. 前文回顾Linux的Dynamic debug功能简单讲了下如何使用。再来回顾下其概念和用法。Dynamic Debug 是 Linux 内核的动态调试功能允许在运行时动态开启/关闭特定的pr_debug()和dev_dbg()输出而无需重新编译内核。核心特点✅ 运行时控制无需重启✅ 精细化控制可按模块、文件、函数、行号过滤✅ 零性能开销关闭时完全无开销✅ 使用 DebugFS 作为控制接口1.1 DebugFS 控制接口主控制文件/sys/kernel/debug/dynamic_debug/control# 查看所有可用的 debug 点$cat/sys/kernel/debug/dynamic_debug/control drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c:123[amdgpu]amdgpu_init_AMDGPU driver loaded\012drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:456[amdgpu]amdgpu_device_init_Device init started\012...# 启用特定模块的所有 debug 输出$echomodule amdgpu p/sys/kernel/debug/dynamic_debug/control# 启用特定文件的 debug 输出$echofile amdgpu_ring.c p/sys/kernel/debug/dynamic_debug/control# 启用特定函数的 debug 输出$echofunc amdgpu_ring_init p/sys/kernel/debug/dynamic_debug/control# 禁用 debug 输出$echomodule amdgpu -p/sys/kernel/debug/dynamic_debug/control2. 内核实现分析位置lib/dynamic_debug.c2.1. 数据结构/* 每个 pr_debug() 对应一个 _ddebug 结构 */struct_ddebug{constchar*modname;/* 模块名 */constchar*function;/* 函数名 */constchar*filename;/* 文件名 */constchar*format;/* 格式字符串 */unsignedintlineno:18;/* 行号 */unsignedintflags:8;/* 标志 (是否启用) */}__attribute__((aligned(8)));/* 标志定义 */#define_DPRINTK_FLAGS_PRINT(10)/* 启用打印 */#define_DPRINTK_FLAGS_INCL_MODNAME(11)#define_DPRINTK_FLAGS_INCL_FUNCNAME(12)#define_DPRINTK_FLAGS_INCL_LINENO(13)2.2. DebugFS 文件操作/* 读操作显示所有 debug 点 */staticintddebug_proc_show(structseq_file*m,void*p){structddebug_iter*iterm-private;struct_ddebug*dpp;charflagsbuf[10];/* 格式化输出每个 debug 点的信息 */seq_printf(m,%s:%u [%s]%s %s \%s\\n,trim_prefix(dp-filename),dp-lineno,iter-table-mod_name,dp-function,ddebug_describe_flags(dp-flags,flagsbuf,sizeof(flagsbuf)),dp-format);return0;}/* 写操作处理控制命令 */staticssize_tddebug_proc_write(structfile*file,constchar__user*ubuf,size_tlen,loff_t*offp){char*tmpbuf;intret;/* 限制输入大小 */if(len0||lenPAGE_SIZE)return-EINVAL;/* 从用户空间复制命令 */tmpbufmemdup_user_nul(ubuf,len);if(IS_ERR(tmpbuf))returnPTR_ERR(tmpbuf);/* 解析并应用控制命令 */retddebug_exec_queries(tmpbuf,NULL);kfree(tmpbuf);if(ret0)returnret;returnlen;}/* file_operations 定义 */staticconststructfile_operationsddebug_proc_fops{.ownerTHIS_MODULE,.openddebug_proc_open,.readseq_read,.llseekseq_lseek,.releaseseq_release_private,.writeddebug_proc_write,};2.3. 初始化staticint__initdynamic_debug_init_debugfs(void){structdentry*dir;/* 创建 dynamic_debug 目录 */dirdebugfs_create_dir(dynamic_debug,NULL);if(!dir)return-ENOMEM;/* 创建 control 文件 */debugfs_create_file(control,0644,dir,NULL,ddebug_proc_fops);return0;}fs_initcall(dynamic_debug_init_debugfs);2.4 pr_debug() 宏实现/* include/linux/dynamic_debug.h */#ifdefCONFIG_DYNAMIC_DEBUG#definepr_debug(fmt,...)\do{\staticstruct_ddebug__aligned(8)\__section(__dyndbg)descriptor{\.modnameKBUILD_MODNAME,\.function__func__,\.filename__FILE__,\.format(fmt),\.lineno__LINE__,\.flags_DPRINTK_FLAGS_DEFAULT,\};\if(unlikely(descriptor.flags_DPRINTK_FLAGS_PRINT))\__dynamic_pr_debug(descriptor,pr_fmt(fmt),\##__VA_ARGS__);\}while(0)#else#definepr_debug(fmt,...)no_printk(fmt,##__VA_ARGS__)#endif工作原理每个pr_debug()编译时生成一个_ddebug结构所有_ddebug放在特殊段__dyndbg中内核启动时收集所有_ddebug结构通过 debugfs 控制flags字段运行时检查flags决定是否打印使用示例驱动代码/* drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c */intamdgpu_ring_init(structamdgpu_device*adev,structamdgpu_ring*ring,unsignedintmax_dw,structamdgpu_irq_src*irq_src){/* 这些 pr_debug 默认不输出 */pr_debug(Initializing ring %s\n,ring-name);pr_debug(Ring size: %u DWs\n,max_dw);/* ... 初始化逻辑 ... */pr_debug(Ring %s initialized successfully\n,ring-name);return0;}运行时控制# 启用该文件的所有 debug 输出$echofile amdgpu_ring.c p/sys/kernel/debug/dynamic_debug/control# 现在执行操作会看到 debug 信息$dmesg|tail[123.456]amdgpu: Initializing ring gfx[123.457]amdgpu: Ring size:1024DWs[123.458]amdgpu: Ring gfx initialized successfully# 禁用$echofile amdgpu_ring.c -p/sys/kernel/debug/dynamic_debug/control高级用法# 按行号启用$echofile amdgpu_ring.c line 123 pcontrol# 组合条件文件 函数$echofile amdgpu_ring.c func amdgpu_ring_init pcontrol# 格式化标志$echomodule amdgpu pflmtcontrol# p: 启用打印# f: 包含函数名# l: 包含行号# m: 包含模块名# t: 包含线程 ID# 使用通配符$echofile amdgpu_* pcontrol $echofunc *_init pcontrol性能影响分析/* 关闭时的性能开销 */if(unlikely(descriptor.flags_DPRINTK_FLAGS_PRINT))// 仅一次位测试__dynamic_pr_debug(descriptor,...);// 不执行/* * unlikely() 提示分支预测优化 * 位测试极快的 CPU 操作 * 关闭时几乎零开销1 纳秒 */与其他调试方式对比方式运行时控制性能开销灵活性需要重启printk❌高低✅Dynamic Debug✅极低高❌Ftrace✅中极高❌条件编译 (#ifdef)❌无低✅学习要点Dynamic Debug 展示了 DebugFS 的典型应用模式复杂的写操作解析用户命令应用配置到内核数据结构错误处理和验证大量数据的读操作使用 seq_file 遍历内核数据格式化输出便于阅读运行时控制内核行为无需重启或重新加载模块即时生效