Linux内核 -- `dynamic_debug` 使用指南

Linux Kernel dynamic_debug 使用指南

在 Linux 内核中,dynamic_debug 是一个非常实用的功能,用于在运行时控制内核代码中的调试信息输出,而不需要重新编译或重启内核。dynamic_debug 提供了对 pr_debug()dev_dbg() 调试信息的动态控制功能,使得开发人员可以根据需要打开或关闭某些模块中的调试信息,从而灵活地定位问题。

1. 动态调试的前置条件

为了使用动态调试功能,内核需要在编译时启用相关选项:

  • 内核配置选项 :需要在内核配置中启用 CONFIG_DYNAMIC_DEBUG,这样才会支持动态调试。

    复制代码
    CONFIG_DYNAMIC_DEBUG=y

2. 语法和用法

动态调试使用 /sys/kernel/debug/dynamic_debug/control 这个接口文件来控制调试信息输出。该文件包含了所有内核中使用了 pr_debug()dev_dbg() 调试宏的条目,并且支持用户通过写入命令来启用或禁用这些调试信息。

要使用动态调试,首先需要挂载 debugfs,例如:

bash 复制代码
mount -t debugfs none /sys/kernel/debug

3. 查询调试信息

可以通过查看 /sys/kernel/debug/dynamic_debug/control 文件,来获取所有支持动态调试的条目:

bash 复制代码
cat /sys/kernel/debug/dynamic_debug/control

这将显示内核中可用的调试信息条目,每一行对应一个调试语句。条目信息通常包括:

  • 文件名
  • 行号
  • 模块名
  • 函数名
  • 状态(是否启用)
  • 格式字符串

示例输出如下:

复制代码
kernel/module.c:100 [module] module_param_call() =_ "Loading module: %s\n"
drivers/net/ethernet/eth.c:200 [eth] eth_open() =p "Opening Ethernet device\n"

字段说明:

  • 文件名:行号:调试信息所在的源文件和行号。
  • [模块名]:模块名称。
  • 函数名():所在的函数。
  • 状态符号:用于表示当前调试状态,符号可能为 ==p,表示是否启用。
  • 格式字符串pr_debug()dev_dbg() 中的内容。

4. 动态控制调试信息

可以通过向 /sys/kernel/debug/dynamic_debug/control 写入命令来控制调试输出,常用的命令格式为:

复制代码
file <filename> line <line_number> <flags>
module <module_name> <flags>
format <format_string> <flags>

其中,<flags> 可以是以下内容的组合:

  • p:启用调试信息(print)。
  • f:在输出中显示函数名称。
  • l:在输出中显示行号。
  • m:在输出中显示模块名称。
  • t:在输出中显示时间戳。

例如:

  1. 启用某个文件中的所有调试信息

    bash 复制代码
    echo 'file eth.c +p' > /sys/kernel/debug/dynamic_debug/control

    这将启用 eth.c 文件中的所有 pr_debug() 调试信息。

  2. 关闭某个模块中的所有调试信息

    bash 复制代码
    echo 'module eth -p' > /sys/kernel/debug/dynamic_debug/control

    这将关闭 eth 模块中的所有调试信息。

  3. 启用特定文件中特定行的调试信息

    bash 复制代码
    echo 'file eth.c line 200 +p' > /sys/kernel/debug/dynamic_debug/control

    这将启用 eth.c 文件中第 200 行的调试信息。

  4. 通过格式字符串启用调试信息

    bash 复制代码
    echo 'format "Loading module*" +p' > /sys/kernel/debug/dynamic_debug/control

    这将启用所有格式字符串中包含 "Loading module*" 的调试信息。

5. 持久化配置

动态调试的设置在重启后会丢失,因此可以将常用的配置添加到系统启动脚本中,比如 /etc/rc.local,这样可以在系统启动时自动应用这些调试设置。

例如,添加以下内容到 /etc/rc.local

bash 复制代码
echo 'module eth +p' > /sys/kernel/debug/dynamic_debug/control

6. 例子

假设你正在调试一个以太网驱动程序,你想查看驱动初始化过程中执行的调试信息,可以使用以下命令:

bash 复制代码
echo 'module eth +p' > /sys/kernel/debug/dynamic_debug/control

然后加载驱动模块或重新启动网络服务,这样就可以看到内核日志中输出的调试信息。

如果你想临时关闭这些调试信息,只需运行:

bash 复制代码
echo 'module eth -p' > /sys/kernel/debug/dynamic_debug/control

7. 实用技巧

  • dmesg 联合使用 :动态调试输出的调试信息通常会被写入内核日志中,因此可以使用 dmesgjournalctl 命令来查看调试输出。

    bash 复制代码
    dmesg | grep eth
  • 减少调试信息:可以只启用对某些特定路径、模块、或者行号的调试信息,减少不必要的信息干扰。

8. 总结

dynamic_debug 是 Linux 内核中非常灵活且强大的调试工具,它允许开发人员在不重启或重新编译内核的情况下动态地控制调试输出。通过它可以轻松启用或禁用特定模块或代码路径中的调试信息,从而帮助开发人员更高效地排查问题。

使用步骤总结如下:

  1. 确保内核配置开启了 CONFIG_DYNAMIC_DEBUG 选项。
  2. 挂载 debugfs 文件系统。
  3. 使用 /sys/kernel/debug/dynamic_debug/control 文件来查询和控制调试信息。
  4. 使用合适的命令启用或禁用调试信息,以更好地排查问题。
相关推荐
yuxb7323 分钟前
Linux 文本处理与 Shell 编程笔记:正则表达式、sed、awk 与变量脚本
linux·笔记·正则表达式
刘一说35 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
wdxylb6 小时前
云原生俱乐部-shell知识点归纳(1)
linux·云原生
飞雪20077 小时前
Alibaba Cloud Linux 3 在 Apple M 芯片 Mac 的 VMware Fusion 上部署的完整密码重置教程(二)
linux·macos·阿里云·vmware·虚拟机·aliyun·alibaba cloud
路溪非溪8 小时前
关于Linux内核中头文件问题相关总结
linux
海绵不是宝宝8179 小时前
连接远程服务器上的 jupyter notebook,解放本地电脑
服务器·jupyter·github
Lovyk10 小时前
Linux 正则表达式
linux·运维
Fireworkitte11 小时前
Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
linux·ubuntu·centos
sword devil90011 小时前
ubuntu常见问题汇总
linux·ubuntu
ac.char12 小时前
在CentOS系统中查询已删除但仍占用磁盘空间的文件
linux·运维·centos