前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux kernel 调试方法总结

Linux kernel 调试方法总结

原创
作者头像
bingwang
修改2024-07-09 19:26:58
2730
修改2024-07-09 19:26:58
举报
文章被收录于专栏:Linux kernel

本文旨在介绍下几种常见的调试方法gdb、crash、kgdb and kdb 以及dynamic debug. 关于在 Linux 内核上使用debuggers,Linus Torvalds 长期以来对它们不太喜欢。简短地解释这种态度是,依赖调试器可能鼓励用权宜之计而非深思熟虑来解决问题,这会导致代码质量恶化。详细解释可以参考https://lwn.net/2000/0914/a/lt-debugger.php3

1. Linux 开发过程中会遇到的问题

Oops:错误报告,可能导致系统不稳定。

Kernel Crash:严重错误导致的系统完全崩溃。

Panic:严重错误,系统停止运行,通常需要重启。

OOM:内存耗尽,触发 OOM Killer。

1.1 Oops

定义:Oops 是 Linux 内核中的一种错误报告,它发生在内核检测到某些违反系统完整性的问题时。通常,这些问题包括非法内存访问、使用未初始化的内存、空指针解引用等。

影响:发生 Oops 后,内核会尝试继续运行,但系统的稳定性可能会受到影响,因为已经发生了内存损坏或其他严重的内核错误。

处理:内核通常会打印错误信息和内核调用栈到系统日志中,这有助于开发人员诊断和修复问题。

1.2 Kernel Crash

定义:Kernel Crash 指的是内核因为严重错误而完全失去功能的情况。它可能是由 Oops 导致的,也可能是由硬件故障、驱动程序错误或其他严重的内核级别问题引起的。

影响:当内核崩溃时,系统通常无法继续运行,需要重启。

处理:系统管理员需要查看崩溃转储或日志文件来分析原因,并采取措施防止未来发生类似崩溃。

1.3 Panic

定义:Kernel Panic 是一种特殊类型的错误,当内核检测到无法恢复的系统错误时触发。这通常表示系统的关键部分已损坏或遇到不可恢复的操作错误。

影响:Panic 通常会导致系统完全停止响应,需要重新启动。

处理:内核会在控制台输出 panic 相关的信息,包括错误描述和内核调用栈。系统通常需要重启才能恢复。

1.4 OOM (Out of Memory)

定义:OOM 错误发生在系统物理内存和交换空间都耗尽时,内核无法满足进程的内存分配请求。

影响:当发生 OOM 时,内核会触发 OOM Killer,尝试终止一个或多个进程来释放内存。

处理:内核选择杀死占用大量内存但相对不重要的进程。这个决定基于一系列启发式评分算法,以最小化对系统整体运行的影响。

2. Linux中常用的调试(debuggers)

2.1 gdb

代码语言:bash
复制
gdb /boot/vmlinux /proc/kcore

当使用上面的命令的时候,实际上是进行的事后调试Post-mortem Debugging

其中第一个参数是当前运行的未压缩的内核。要调试的内核必须用-g选线编译并且获得调试信息。vmlinuz 是 vmlinux 的压缩版本,添加了自解压头部,使其可以自我解压并执行。

上面的命令需要在编译内核的时候打开下面的选项,其实也就是CONFIG_DEBUG_INFO

代码语言:txt
复制
Kernel hacking  --->
    [*] Compile the kernel with debug info

/proc/kcore 是一个虚拟文件,提供了对当前运行系统物理内存的映射,其格式模仿了一个核心转储(core dump)。虽然 /proc/kcore 表现得像是一个内存转储文件,但它实际上是一个实时的视图,反映了当前系统的内存状态。

2.2 crash

使用 crash 工具来分析 Linux 内核崩溃是一个强大的方法,它可以帮助你理解内核崩溃时的状态,包括堆栈跟踪、内存状态、寄存器内容等。crash 主要用于分析由 kdump 服务生成的内核崩溃转储(vmcore 文件)。以下是如何设置和使用 crash 的步骤和示例:

代码语言:bash
复制
sudo apt install kdump-tools crash
sudo systemctl enable kdump
sudo systemctl start kdump
#trigger crash for test purpose
echo c > /proc/sysrq-trigger
sudo crash /path/to/vmlinux /path/to/vmcore

在 crash 环境中,你可以执行多种命令来分析崩溃:

代码语言:bash
复制
	bt:显示当前 CPU 或特定进程的堆栈跟踪。
	ps:显示系统中的进程状态。
	vm:查看内存信息。
	log:显示内核日志。
	例如,要获取当前环境的堆栈跟踪,可以运行:
    bt

假设系统因为某个驱动错误而崩溃,已经通过上述步骤获得了 vmcore 文件。现在,可以使用 crash 来分析驱动中可能的错误位置,检查在崩溃时的函数调用堆栈,以及查看那时的内存状态和变量。

通过这样的分析,可以精确地定位到问题发生的代码行,从而更有针对性地解决问题。此外,分析内核日志(通过 log 命令)可以帮助了解crash前发生了什么,这对于理解错误的上下文非常有帮助。

2.3 kgdb

KGDB 适合深入的远程内核调试,而 KDB 更适合快速本地访问和简单问题的诊断。两者的使用依赖于具体的调试需求和环境设置。

kgdb的使用步骤如下:

2.3.1 准备内核

代码语言:txt
复制
Kernel hacking  --->
  <*> KGDB: kernel debugger  --->
    [*] KGDB: use kgdb over the serial console
    [ ] KGDB: internal test suite
    [ ] KGDB_KDB: include kdb frontend for kgdb
    [ ] KGDB over Ethernet

2.3.2 添加启动参数

代码语言:txt
复制
kgdboc=ttyS0,115200 kgdbwait

2.3.3 调试机(host)上启动gdb作为前端

代码语言:bash
复制
gdb /path/to/vmlinux

2.3.4 设置远程调试目标:

代码语言:bash
复制
(gdb) target remote /dev/ttyS0

一旦连接成功,可以使用 GDB 的各种命令来进行断点设置、单步执行、变量检查等调试任务。

2.4 kdb

KDB 是内核内置的调试器,可以通过键盘直接激活

2.4.1 准备内核

代码语言:txt
复制
Kernel hacking  --->
  <*> Kernel debugging  --->
    <*> Kernel debugger (KDB)
    <*>   Support for kgdb over the serial console

2.4.2 启动配置了KDB支持的内核,无需额外启动参数

2.4.3 激活KDB

通过触发系统崩溃(如 Magic SysRq 键组合)或通过预设断点来激活 KDB。

在键盘上按下 Alt+SysRq+G 可以激活 KDB。

2.4.4 使用KDB

代码语言:txt
复制
	在 KDB 提示符下,你可以使用命令来查看堆栈、寄存器、内存等:
	bt:查看当前的调用堆栈。
	rd:查看寄存器内容。
	md:查看内存地址的内容。

2.5 dynamic debug

dynamic debug 无需重新编译内核,可以根据需求打开特定的模块的打印选项。这对于理解和调试内核非常有用。可以参考下面的文档。

2.5.1 准备内核

代码语言:txt
复制
Kernel hacking  --->
  [*] Enable dynamic printk() call support

2.5.2 查看可用的动态调试点

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

2.5.3 启用调试命令

代码语言:bash
复制
echo 'func my_function +p' > /sys/kernel/debug/dynamic_debug/control

更多细节请参考动态debug的内核

https://www.kernel.org/doc/html/v4.14/admin-guide/dynamic-debug-howto.html

3. 结束语

通过有效地使用这些工具,Linux 内核开发者可以更有效地定位和解决内核级别的问题。从实时调试复杂的驱动问题(使用 KGDB)到快速查看系统状态(使用 KDB),或者动态调整调试输出(使用 Dynamic Debug),这些工具为我们提供了强大的支持。随着技术的进步和内核的发展,这些调试方法将继续发挥关键作用,帮助开发者优化内核性能和稳定性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Linux 开发过程中会遇到的问题
    • 1.1 Oops
      • 1.2 Kernel Crash
        • 1.3 Panic
          • 1.4 OOM (Out of Memory)
          • 2. Linux中常用的调试(debuggers)
            • 2.1 gdb
              • 2.2 crash
                • 2.3 kgdb
                  • 2.4 kdb
                    • 2.5 dynamic debug
                    • 3. 结束语
                    相关产品与服务
                    远程调试
                    远程调试(Remote Debugging,RD)在云端为用户提供上千台真实手机/定制机/模拟器设备,快速实现随时随地测试。运用云测技术对测试方式、操作体验进行了优化,具备多样性的测试能力,包括随时截图和记录调试日志,稳定的支持自动化测试, 设备灵活调度,用例高效执行, 快速定位产品功能和兼容性问题。云手机帮助应用、移动游戏快速发现和解决问题,节省百万硬件费用,加速敏捷研发流程。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档