多行搜索,正在匹配代码
多行搜索,正在匹配 如下代码:
}
__setup(xxx
多行搜索,正则匹配 如下代码:
}
__setup(xxx
要匹配以 }
结尾的行及其下一行以 __setup(
开头的模式,可以使用以下正则表达式(支持多行搜索):
1 | import re |
代码说明:
正则表达式分解:
^\}
:匹配行首的}
字符(^
表示行首)。\s*
:匹配可能的空白字符(空格/制表符等)。\n
:匹配换行符。__setup\(
:匹配下一行开头的固定字符串__setup(
。.*?$
:匹配该行剩余内容直到行尾($
)。
关键标志:
re.MULTILINE
:使^
和$
匹配每行的开头和结尾(而非整个字符串)。
输出示例:
对于上面的示例文本,输出结果为:
1 | ['}\n__setup(xxx', '}\n __setup(xxx'] |
根据需求调整:
- 如果需捕获
xxx
部分,使用分组:1
pattern = r'^\}\s*\n__setup\((.*?)\)?$' # 捕获括号内的内容
- 如果需处理 Windows 换行符(
\r\n
):1
pattern = r'^\}\s*\r?\n__setup\(.*?$' # \r? 兼容 \r\n 和 \n
此方案直接解决多行匹配需求,并兼容常见空白符和换行格式。
Linux内核中__setup返回值的作用
在 Linux 内核中,__setup
宏用于注册内核命令行参数的处理函数,其注册的处理函数返回值决定了该参数是否从内核命令行中移除。具体作用如下:
1. 返回值的作用
当内核解析到匹配的命令行参数时,会调用通过 __setup
注册的处理函数:
- 返回
1
:表示参数未被完全处理,该参数会被保留在内核命令行中(后续可能被其他处理函数或用户空间进程使用) - 返回
0
:表示参数已处理完毕,该参数会从内核命令行中移除(不会传递给用户空间)
2. 使用示例
1 | // 注册命令行参数处理函数 |
3. 内部机制
当内核启动时,会调用 parse_args()
处理命令行参数:
1 | // 内核源码示例 (init/main.c) |
在 parse_one()
中:
1 | // 简化的处理逻辑 |
4. 典型应用场景
返回值 | 使用场景 | 示例参数 |
---|---|---|
0 | 已处理的专用参数 | console=ttyS0 |
1 | 需要传递给用户空间的参数 | root=/dev/sda1 |
1 | 格式错误需保留供其他处理的参数 | 无法识别的参数值 |
5. 注意事项
- 早期初始化:
__setup
处理函数在内核初始化早期执行(在内存管理完全初始化之前) - 字符串格式:参数格式应为
param=value
,处理函数接收value
部分 - 替代方案:现代内核推荐使用
early_param()
,它在更早阶段执行 - 内存限制:处理函数不能使用动态内存分配(此时内存管理未完全初始化)
6. 实际内核示例
1 | // 内核源码示例 (kernel/reboot.c) |
总结:__setup
处理函数的返回值是内核命令行参数处理流程的关键控制点,通过返回 0
或 1
决定参数是否从内核命令行中移除,直接影响参数是否传递给用户空间进程。
Linux使能dynamic debug打印
在 Linux 内核中,Dynamic Debug(动态调试) 功能允许在运行时动态启用或禁用内核中的调试打印语句(如 pr_debug()
、dev_dbg()
)。以下是启用和使用 Dynamic Debug 的完整指南:
一、启用 Dynamic Debug 的必要条件
内核配置:
1
2
3
4
5# 启用 CONFIG_DYNAMIC_DEBUG
CONFIG_DYNAMIC_DEBUG=y
# 启用 DEBUG_FS(提供控制接口)
CONFIG_DEBUG_FS=y通过
make menuconfig
确认:1
2
3Kernel hacking ->
[*] Enable dynamic printk() support
[*] Debug Filesystem挂载 debugfs:
1
sudo mount -t debugfs none /sys/kernel/debug
二、控制 Dynamic Debug 的三种方式
方法 1:通过 /sys/kernel/debug/dynamic_debug/control
文件
这是最常用的动态控制方式:
1 | # 1. 查看当前所有调试点 |
方法 2:通过内核启动参数
在内核命令行中添加 dyndbg
参数:
1 | # 在 GRUB 配置 /boot/grub/grub.cfg 中添加: |
或使用模块特定参数:
1 | modprobe nvidia dyndbg=+p |
方法 3:在代码中直接启用
在驱动代码中添加:
1 |
|
三、控制指令详解
指令 | 作用 | 示例 |
---|---|---|
+p |
启用打印 | file ext4*.c +p |
-p |
禁用打印 | module usb_storage -p |
+l |
添加行号信息 | func foo* +l |
+m |
添加模块名信息 | file net/*.c +m |
+t |
添加线程ID信息 | func bar +t |
范围限定 | 按文件/函数/模块/行号过滤 | file driver.c line 100-200 +p |
四、实际使用示例
场景:调试 USB 存储驱动
1 | # 1. 启用所有 usb-storage 相关调试 |
场景:调试特定文件的某几行
1 | # 启用 ext4/inode.c 中 100-200 行的调试 |
五、高级技巧
组合使用标志:
1
2# 启用打印并显示行号、模块名
sudo echo "file net/core/dev.c +pml" > /sys/kernel/debug/dynamic_debug/control查询当前状态:
1
2# 显示所有已启用的调试点
grep "+p" /sys/kernel/debug/dynamic_debug/control永久生效:
在/etc/modprobe.d/debug.conf
中添加:1
options usb_storage dyndbg=+p
六、工作原理
- 当使用
pr_debug()
或dev_dbg()
时,这些调用会被编译进特殊段.data._dyndbg
- 内核启动时解析这些调试描述符
- 通过 debugfs 接口动态修改标志位
- 打印函数执行前会检查
DYNAMIC_DEBUG_BRANCH
宏
七、注意事项
- 性能影响:启用大量调试打印会显著降低系统性能
- 日志风暴:避免在生产环境启用,可能刷屏内核日志
- 依赖关系:需确保
debugfs
已挂载 - 内核版本:完整功能需要 Linux 3.0+ 内核
通过 Dynamic Debug,您可以在不重启系统、不重新编译内核的情况下,精准控制调试信息的输出,极大提高内核调试效率。
如何查看linux内核动态打印日志
查看 Linux 内核动态打印日志的完整指南
在 Linux 中使用动态调试(Dynamic Debug)功能后,查看生成的调试日志有几种主要方法。以下是最常用的查看方式及其详细说明:
一、核心查看方法
1. 使用 dmesg
命令(推荐)
1 | # 实时查看新日志(按 Ctrl+C 退出) |
2. 使用 journalctl
命令(systemd 系统)
1 | # 实时查看内核日志 |
3. 直接读取内核日志缓冲区
1 | # 方法1:通过 /proc/kmsg(需要 root) |
二、优化日志查看体验
1. 提高日志缓冲区大小
1 | # 临时增大内核日志缓冲区(128K→2M) |
2. 日志级别过滤
1 | # 显示所有级别日志(默认只显示 warn 以上) |
3. 彩色输出和人性化时间戳
1 | # 安装彩色支持 |
三、高级调试技巧
1. 特定模块日志过滤
1 | # 跟踪 USB 存储模块日志 |
2. 将日志保存到文件
1 | # 保存日志到文件(后台运行) |
3. 使用专用工具
1 | # 安装内核日志查看专用工具 |
四、动态调试日志识别特征
动态调试日志通常有以下特征:
- 前缀为
[dyn]
或模块名 - 包含
DEBUG
标识 - 有额外的上下文信息(如行号、函数名)
示例日志:
1 | [ 1234.567890] usb_storage: [dyn] scsi_add_host: line 128: Adding host for USB device |
五、常见问题解决
问题1:看不到任何输出
解决方案:
- 确认已启用动态调试:
1
grep "DYNAMIC_DEBUG" /boot/config-$(uname -r)
- 检查 debugfs 是否挂载:
1
mount | grep debugfs
- 确认已启用打印标志:
1
cat /sys/kernel/debug/dynamic_debug/control | grep "+p"
问题2:日志被刷屏太快
解决方案:
1 | # 限制输出速率 |
问题3:日志不包含源代码位置
解决方案:
启用行号和模块名:
1 | # 添加行号信息 |
六、最佳实践建议
精确控制:只启用需要的模块/文件,避免日志洪水
1
echo "file drivers/usb/storage/* +p" > /sys/kernel/debug/dynamic_debug/control
时间同步:确保系统时间准确,方便日志分析
1
sudo timedatectl set-ntp true
日志轮转:防止日志填满磁盘
1
2sudo apt install logrotate
sudo nano /etc/logrotate.d/dmesg远程日志:对于嵌入式系统,配置远程日志
1
2# 在 /etc/rsyslog.conf 添加:
kern.* @192.168.1.100:514
通过以上方法,您可以高效地查看和分析 Linux 内核的动态调试日志。对于生产环境,建议结合 systemd-journald
的持久化日志功能,确保关键调试信息不会丢失。