2023-09-0820发布于天津
版权
简介: Linux内核基础篇——动态输出调试

上篇说到printk调试,但printk是全局的,只能设置输出等级。而动态输出可以动态选择打开某个内核子系统的输出,可以有选择性地打开某些模块的输出。
要使用动态输出,必须在配置内核时打开CONFIG_DYNAMIC_DEBUG宏。内核代码里使用大量pr_debug()/dev_dbg()函数来输出信息,这些就使用了动态输出。
需要打开的内核配置选项:
CONFIG_DEBUG_FS=y CONFIG_DYNAMIC_DEBUG=y

CONFIG_DYNAMIC_DEBUG是配置动态输出,它依赖于CONFIG_DEBUG_FS,而CONFIG_DEBUG_FS是debugfs文件系统。
打开内核配置后,我们还需要挂载debugfs文件系统。
动态输出在debugfs文件系统中有一个control文件节点,这个文件节点记录了系统中所有使用动态输出技术的文件名路径、输出所在的行号、模块名字和要输出的语句。
debugfs默认会挂载到/sys/kernel/debug,如果没有挂载,可以执行以下命令挂载:
# mount -t debugfs none /sys/kernel/debug/
挂载debugfs文件系统后,可以查看control节点内容:
# cat /sys/kernel/debug/dynamic_debug/control
打开svcsock.c文件中所有的动态输出语句
# echo 'file svcsock.c +p' > /sys/kernel/debug/dynamic_debug/control
打开usbcore模块中所有的动态输出语句
# echo 'module usbcore +p' > /sys/kernel/debug/dynamic_debug/control
打开svc_process()函数中所有的动态输出语句
# echo 'func svc_process() +p' > /sys/kernel/debug/dynamic_debug/control
打开文件路径包含usb的文件里所有的动态输出语句
# echo -n '*usb* +p' > /sys/kernel/debug/dynamic_debug/control
打开系统所有的动态输出语句
# echo -n '+p' > /sys/kernel/debug/dynamic_debug/control
上面是打开动态输出语句的例子,除了能输出pr_debug()/dev_dbg()函数中定义的输出信息外,还能输出一些额外信息,如函数名、行号、模块名字以及线程ID等