SuperAPI AI 工具集

kernel-debugging

部署与运维

查看项目

更新于 10-15 15:12

技能介绍

用途

本技能用于指导智能体调试 Linux 内核,涵盖以下范围:通过串口或 USB 使用 kgdb、kdb 内置调试器命令、ftrace 与 trace-cmd、kprobes 与 kretprobes、动态调试(dyndbg)、使用 crash 和 makedumpfile 进行崩溃转储分析、dmesg 日志级别,以及用于调试的 /proc/sys 运行时调优。

适用时机

  • 内核 panic 或 oops,栈回溯不清晰
  • 使用 kgdb 实时调试内核模块或驱动
  • 无需重新编译即可追踪函数调用(ftrace、kprobes)
  • 使用 dyndbg 开启驱动详细日志
  • 分析来自 kdump 的生产环境崩溃转储
  • 为调试会话调整内核运行时参数

工作流

1. dmesg 与日志级别

# 内核环形缓冲区
dmesg -T -l err,warn
dmesg -w   # 实时跟随

# 日志级别(0=emerg .. 7=debug)
cat /proc/sys/kernel/printk
# current  default  minimum  boot-default
# 4        4        1        7

# 临时提高详细程度
echo 8 > /proc/sys/kernel/printk

内核 printk 级别:从 KERN_EMERG 到 KERN_DEBUG。驱动的 dev_dbg() 需要 dyndbg 或 DEBUG 定义。

2. 串口上的 kgdb

内核配置:CONFIG_KGDB、CONFIG_KGDB_SERIAL_CONSOLE。

# 启动参数(ttyS0, 115200)
kgdboc=ttyS0,115200 kgdbwait

# 或在运行时
echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc
echo g > /proc/sysrq-trigger   # 进入 kgdb

GDB 主机侧:

# 连接到远程串口
gdb vmlinux
(gdb) set serial baud 115200
(gdb) target remote /dev/ttyUSB0
(gdb) bt
(gdb) list *panic+0x20

USB 变体:在支持的硬件上使用 CONFIG_KGDB_KDB 配合 kgdboc=usb。

3. kdb 命令

启用 CONFIG_KGDB_KDB 后,kdb 提供内核内 shell:

kdb 命令(在 SysRq 断点处):

  • bt — 栈回溯
  • lsmod — 已加载模块
  • md <addr> — 内存显示
  • ps — 进程列表
  • id <cpu> — CPU 寄存器
  • go — 继续执行
  • cpu <n> — 切换 CPU 上下文
# 进入 kdb
echo k > /proc/sysrq-trigger

4. ftrace

# 启用函数追踪器
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on

# 过滤到特定函数
echo schedule > /sys/kernel/debug/tracing/set_ftrace_filter
echo ':*probe_*' >> /sys/kernel/debug/tracing/set_ftrace_notrace

# 捕获并读取
cat /sys/kernel/debug/tracing/trace_pipe

# 关闭
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo nop > /sys/kernel/debug/tracing/current_tracer

# trace-cmd(用户态记录器)
trace-cmd record -p function -l schedule,do_page_fault
trace-cmd report
trace-cmd.dat  # kernelshark GUI

5. kprobes 与 kretprobes

# 通过 debugfs 动态 kprobe
echo 'p:myprobe do_sys_open %ax %si' > /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
cat /sys/kernel/debug/tracing/trace

# kretprobe
echo 'r:myretprobe do_sys_open $retval' >> /sys/kernel/debug/tracing/kprobe_events

# 清理
echo 0 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo '-:myprobe' > /sys/kernel/debug/tracing/kprobe_events

内核内 kprobe(模块):

#include <linux/kprobes.h>

static struct kprobe kp = {
    .symbol_name = "do_sys_open",
    .pre_handler = my_pre_handler,
};

static int __init mod_init(void)
{
    return register_kprobe(&kp);
}

6. 动态调试(dyndbg)

# 为模块启用所有调试消息
echo 'module mydriver +p' > /sys/kernel/debug/dynamic_debug/control

# 启用特定文件:行
echo 'file drivers/i2c/i2c-core.c +p' > /sys/kernel/debug/dynamic_debug/control

# 查询当前设置
grep mydriver /sys/kernel/debug/dynamic_debug/control

启动时:在内核命令行使用 dyndbg="module mydriver +p"。

7. kdump 与崩溃分析

# 设置 kdump(崩溃内核保留内存)
# /etc/default/grub: crashkernel=256M
sudo kdump-config show

# 崩溃后,vmcore 位于 /var/crash/
ls /var/crash/*/vmcore

# 使用 crash 工具分析
crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/*/vmcore

crash> bt
crash> log
crash> ps
crash> kmem -i
crash> mod

# 压缩 vmcore
makedumpfile -c -d /proc/vmcore /tmp/vmcore.lzo

8. 用于调试的 /proc/sys 运行时调优

# oops 时 panic(在虚拟机中复现)
sysctl kernel.panic_on_oops=1

# 软锁检测
sysctl kernel.softlockup_panic=1

# 看门狗
sysctl kernel.nmi_watchdog=1

# Slab 调试
# 启动参数:slub_debug=P,pagealloc

9. 调试决策树

内核问题类型?

  • Panic/oops → dmesg;crash vmcore;CONFIG_DEBUG_INFO_BTF
  • 驱动逻辑错误 → dyndbg;ftrace function_graph
  • 性能回退 → perf record -g -a;trace-cmd
  • 间歇性问题 → 在可疑路径上使用 kprobes
  • 模块崩溃 → kgdb;try_module_get 审计

常见问题

现象 原因 修复
kgdb 无法连接 tty/波特率错误 将 kgdboc 与串口适配器匹配
ftrace 追踪为空 tracing_off 或 nop 追踪器 echo function > current_tracer;启用 tracing_on
kprobe 注册失败 缺少 CONFIG_KPROBES 或函数被内联 使用 tracepoint 或 static_key
dyndbg 无效 CONFIG_DYNAMIC_DEBUG 未启用 使用该选项重新编译内核
crash 无法读取 vmcore vmlinux 调试符号错误 安装 linux-image-$(uname -r)-dbg
SysRq 不工作 kernel.sysrq 被禁用 echo 1 > /proc/sys/kernel/sysrq

相关技能

  • linux-kernel-modules — 正在被调试的模块开发
  • device-drivers — 驱动特定的探测/中断问题
  • kernel-internals — 用于解释追踪的子系统知识
  • gdb — 与 kgdb 共享的 GDB 命令
  • linux-perf — 用于内核热点的 perf
  • ebpf — 非侵入式内核追踪替代方案

限制

资料未提供该技能的具体实现机制、安装步骤或依赖环境说明,仅列出工作流与常见问题;部分配置项的实际效果可能依赖具体内核版本与硬件,资料中暂未提供相关说明。