mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-25 00:50:15 +08:00
PUB:20140718 Linux Kernel Testing and Debugging 4
@bazz2
This commit is contained in:
parent
c8cb0e501e
commit
ed9f3a546b
@ -1,4 +1,4 @@
|
||||
Linux 内核测试和调试 - 4
|
||||
Linux 内核测试和调试(4)
|
||||
================================================================================
|
||||
### 自动测试工具 ###
|
||||
|
||||
@ -38,11 +38,11 @@ Linux 内核本身包含很多调试功能,比如 kmemcheck 和 kmemleak。
|
||||
|
||||
#### kmemcheck ####
|
||||
|
||||
> kmemcheck 是一个动态检查工具,可以检测出一些未被初始化的内存(LCTT:内核态使用这些内存可能会造成系统崩溃)并发出警告。它的功能与 Valgrind 类似,只是 Valgrind 运行在用户态,而 kmemchecke 运行在内核态。编译内核时加上 CONFIG_KMEMCHECK 选项打开 kmemcheck 调试功能。你可以阅读 Documentation/kmemcheck.txt 来学习如何配置使用这个功能,以及如何看懂调试结果。
|
||||
> kmemcheck 是一个动态检查工具,可以检测出一些未被初始化的内存(LCTT:内核态使用这些内存可能会造成系统崩溃)并发出警告。它的功能与 Valgrind 类似,只是 Valgrind 运行在用户态,而 kmemchecke 运行在内核态。编译内核时加上 `CONFIG_KMEMCHECK` 选项打开 kmemcheck 调试功能。你可以阅读 Documentation/kmemcheck.txt 来学习如何配置使用这个功能,以及如何看懂调试结果。
|
||||
|
||||
#### kmemleak ####
|
||||
|
||||
> kmemleak 通过类似于垃圾收集器的功能来检测内核是否有内存泄漏问题。而 kmemleak 与垃圾收集器的不同之处在于前者不会释放孤儿目标(LCTT:不会再被使用的、应该被释放而没被释放的内存区域),而是将它们打印到 /sys/kernel/debug/kmemleak 文件中。用户态的 Valgrind 也有一个类似的功能,使用 --leak-check 选项可以检测并报错内存泄漏问题,但并不释放这个孤儿内存。编译内核时使用 CONFIG_DEBUG_KMEMLEAK 选项打开 kmemcleak 调试功能。阅读 Documentation/kmemleak.txt 来学习怎么使用这个工具并读懂调试结果。
|
||||
> kmemleak 通过类似于垃圾收集器的功能来检测内核是否有内存泄漏问题。而 kmemleak 与垃圾收集器的不同之处在于前者不会释放孤儿目标(LCTT:不会再被使用的、应该被释放而没被释放的内存区域),而是将它们打印到 /sys/kernel/debug/kmemleak 文件中。用户态的 Valgrind 也有一个类似的功能,使用 --leak-check 选项可以检测并报错内存泄漏问题,但并不释放这个孤儿内存。编译内核时使用 `CONFIG_DEBUG_KMEMLEAK` 选项打开 kmemcleak 调试功能。阅读 Documentation/kmemleak.txt 来学习怎么使用这个工具并读懂调试结果。
|
||||
|
||||
### 内核调试接口 ###
|
||||
|
||||
@ -54,13 +54,13 @@ Linux 内核通过配置选项、调试用的 API、接口和框架来支持动
|
||||
|
||||
### 调试的 API ###
|
||||
|
||||
调试 API 的一个很好的例子是 DMA-debug,用来调试驱动是否错误使用了 DMA 提供的 API。它会跟踪每个设备的映射关系,检测程序有没有试图为一些根本不存在的映射执行“取消映射”操作,检测代码建立 DMA 映射后可能产生的“映射丢失”的错误。内核配置选项 CONFIG_HAVE_DMA_APT_DEBUG 和 CONFIG_DMA_API_DEBUG 可以为内核提供这个功能。其中,CONFIG_DMA_API_DEBUG 选项启用后,内核调用 DMA 的 API 的同时也会调用 Debug-dma 接口。举例来说,当一个驱动调用 dma_map_page() 函数来映射一个 DMA 缓存时,dma_map_page() 会调用debug_dma_map_page() 函数来跟踪这个缓存,直到驱动调用 dma_unmap_page() 来取消映射。详细内容请参考[使用 DMA 调试 API 检测潜在的数据污染和内存泄漏问题][3]。
|
||||
调试 API 的一个很好的例子是 DMA-debug,用来调试驱动是否错误使用了 DMA 提供的 API。它会跟踪每个设备的映射关系,检测程序有没有试图为一些根本不存在的映射执行“取消映射”操作,检测代码建立 DMA 映射后可能产生的“映射丢失”的错误。内核配置选项 `CONFIG_HAVE_DMA_APT_DEBUG` 和 `CONFIG_DMA_API_DEBUG` 可以为内核提供这个功能。其中,`CONFIG_DMA_API_DEBUG` 选项启用后,内核调用 DMA 的 API 的同时也会调用 Debug-dma 接口。举例来说,当一个驱动调用 `dma_map_page()` 函数来映射一个 DMA 缓存时,`dma_map_page()` 会调用`debug_dma_map_page()` 函数来跟踪这个缓存,直到驱动调用 `dma_unmap_page()` 来取消映射。详细内容请参考[使用 DMA 调试 API 检测潜在的数据污染和内存泄漏问题][3]。
|
||||
|
||||
### 动态调试 ###
|
||||
|
||||
动态调试功能就是你可以决定在程序运行过程中是否要 pr_debug(), dev_dbg(), print_hex_dump_debug(), print_hex_dump_bytes() 这些函数正常运行起来。什么意思?当程序运行过程中出现错误时,你可以指定程序打印有针对性的、详细的调试信息。这功能牛逼极了,我们不再需要为了添加调试代码定位一个问题,而重新编译安装内核。你可以指定 CONDIF_DYNAMIC_DEBUG 选项打开动态调试功能,然后通过 /sys/kernel/debug/dynamic_debug/control 接口指定要打印哪些调试日志。下面分别列出代码级别和模块级别打印日志的操作方法:
|
||||
动态调试功能就是你可以决定在程序运行过程中是否要 `pr_debug()`, `dev_dbg()`, `print_hex_dump_debug()`, `print_hex_dump_bytes()` 这些函数正常运行起来。什么意思?当程序运行过程中出现错误时,你可以指定程序打印有针对性的、详细的调试信息。这功能牛逼极了,我们不再需要为了添加调试代码定位一个问题,而重新编译安装内核。你可以指定 `CONDIF_DYNAMIC_DEBUG` 选项打开动态调试功能,然后通过 `/sys/kernel/debug/dynamic_debug/control` 接口指定要打印哪些调试日志。下面分别列出代码级别和模块级别打印日志的操作方法:
|
||||
|
||||
让 kernel/power/suspend.c 源码第340行的 pr_debug() 函数打印日志:
|
||||
让 kernel/power/suspend.c 源码第340行的 `pr_debug()` 函数打印日志:
|
||||
|
||||
echo 'file suspend.c line 340 +p' > /sys/kernel/debug/dynamic_debug/control
|
||||
|
||||
@ -72,7 +72,7 @@ Linux 内核通过配置选项、调试用的 API、接口和框架来支持动
|
||||
|
||||
> 编辑 /etc/modprobe.d/modname.conf 文件(没有这个文件就创建一个),添加 dyndbg='plmft' 选项。然而对于哪些通过 initramfs 加载的驱动来说,这个配置基本无效(LCTT:免费奉送点比较高级的知识哈。系统启动时,需要先让 initramfs 挂载一个虚拟的文件系统,然后再挂载启动盘上的真实文件系统。这个虚拟文件系统里面的文件是 initramfs 自己提供的,也就是说你在真实的文件系统下面配置了 /etc/modprobe.d/modname.conf 这个文件,initramfs 是压根不去理会的。站在内核驱动的角度看:如果内核驱动在 initramfs 过程中被加载到内核,这个驱动读取到的 /etc/modprobe.d/modname.conf 是 initramfs 提供的,而不是你编辑的那个。所以会有上述“写了配置文件后重启依然无效”的结论)。对于这种刁民,呃,刁驱动,我们需要修改 grub 配置文件,在 kernel 那一行添加 module.dyndbg='plmft' 参数,这样你的驱动就可以开机启动动态调试功能了。
|
||||
|
||||
想打印更详细的调试信息,可以使用 dynamic_debug.verbose=1 选项。参考 Documentation/dynamic-debug-howto.txt 文件获取更多信息。
|
||||
想打印更详细的调试信息,可以使用 `dynamic_debug.verbose=1` 选项。参考 Documentation/dynamic-debug-howto.txt 文件获取更多信息。
|
||||
|
||||
### 设置追踪点 ###
|
||||
|
Loading…
Reference in New Issue
Block a user