本技能提供 Linux 内核 vmcore 深度分析的完整工作流,结合 AiCrasher MCP 工具实现自动化 crash 调试。
| 阶段 | 名称 | 核心动作 | 产出/检查点 | 是否必须 |
|---|---|---|---|---|
| ------ | ------ | --------- | ------------ | --------- |
| 阶段零 | 前置环境检查 | 检查 crash 命令、安装 aicrasher、注册 MCP Server、验证 MCP 可调用 | MCP 可用 | ✅ 必须 |
| 阶段一 | 初始化与基线收集 | analyze_crash 创建 session → 收集 sys/bt/log | session_id 已获取 | ✅ 必须 |
| 阶段二 | 识别 Panic 类型 | 根据基线判断 crash 类型 | 明确 panic 类型 | ✅ 必须 |
| 阶段三 | 深入分析 | 根据类型执行对应分析命令 | 证据链完整,根因定位,并明确根因分类 | ✅ 必须 |
| 阶段四 | 查找社区 fix commit 及 bug issue | 搜索上游 git 仓库或 web 搜索修复补丁,搜索社区 bug/issue 报告,若用户提供了发行版 git 仓库则检查新版本是否已修复并定位修复 tag | fix commit 列表 + 相关 bug issue + 发行版修复状态 | ⚡ 条件执行 |
| 阶段五 | 缓解措施分析 | 评估业务优化和内核参数调整 | 可行性建议 | ✅ 必须 |
| 阶段六 | 输出分析报告 | 获取 TIME → Markdown → 脚本生成 HTML 报告 | .md + .html 报告 | ✅ 必须 |
| 阶段七 | 关闭 session | close_crash_session 释放资源 | session 已关闭 | ✅ 必须 |
⚠️ 常见遗漏提醒:
🔴🔴🔴 阶段切换铁律(防止长对话中遗忘 skill 要求):
references/phases/phase4_community_fix.md,进入阶段六前必须读取 references/phases/phase6_report.md)在执行任何 vmcore 分析之前,必须先确认 AiCrasher MCP Server 已安装并注册。
👉 必须完整读取详细步骤文件:references/phases/phase0_setup.md,按步骤 0.0~0.6 逐一执行。
> 🔴 首次注册须知: MCP Server 的发现和连接发生在会话启动时。如果 aicrasher 是在当前会话中首次注册的,当前会话无法热加载,必须提示用户退出并重新启动会话(codebuddy / claude / openclaw),新会话会自动连接已注册的 MCP Server。详见 phase0_setup.md 步骤 0.4 后的说明。
👉 进入阶段一前,必须完整读取:references/phases/mcp_tools_rules.md
核心铁律摘要(详情见上述文件):
execute_command 直接调用 crash、禁止 Python 底层 API 绕过。只能用 session 内已注册的 MCP 工具直接调用;禁止通过 Bash 调用 CLI 的 mcp 子命令bt -a | grep -c '<关键函数>' 统计全局状态sym 命令只能搜索全局符号(全局变量、函数名),无法找到结构体字段。大量内核 sysctl 参数(如 IPVS 的 net.ipv4.vs.*、netfilter 的参数等)是存储在 per-netns 结构体字段中的,不是独立的全局变量grep -rn "<参数名>" <内核源码目录> 在源码中搜索参数定义,确认是否存在、在哪个结构体中、是哪个 sysctl procnamenetns_ipvs、netns_sysctl),确认字段名和偏移量dis ,确认编译后的二进制中是否包含该参数的条件判断逻辑,从反汇编中获取结构体字段的实际偏移量rd 或 p/d (int ) 读取实际值net.ipv4.vs.*)→ 存储在 struct netns_ipvs 字段中,通过 inline 函数访问net.ipv4.conf.、net.core.)→ 存储在 per-netns 结构体中sym 搜索不到sym -q <参数名> 搜索不到就断言"参数不存在"。必须结合源码和反汇编交叉验证crash ps 输出的 VSZ 和 RSS 单位是 KB(千字节),不是 pagesRSS(GB) = RSS(KB) / 1024 / 1024mm->total_vm(单位:pages)× 4096 / 1024 = VSZ(KB),两者必须一致ps -G(线程组 leader)避免同一进程的多个线程被重复统计kmem -i),如果超出说明单位搞错或存在重复计数```bash
TIME=$(date '+%Y%m%d_%H%M') && echo "TIME=$TIME"
```
analyze_crash,cmd_log_path 设为 /crash_cmd_log_${TIME}.jsonl sys(内核版本、运行时长、panic 原因)、bt(panic CPU 调用栈)、log | tail -n 100(最后的内核日志)DISTRO_GIT_REPO 变量,阶段四将用它检查新版本是否已修复DISTRO_GIT_REPO 为空,阶段四跳过仓库修复检查| 类型 | 典型特征 |
|---|---|
| ------ | --------- |
| Hung Task | khungtaskd、"blocked for more than" |
| Soft Lockup | "BUG: soft lockup"、watchdog |
| Hard Lockup | "NMI watchdog: Watchdog detected hard LOCKUP" |
| BUG_ON | "kernel BUG at" |
| NULL 指针 | "unable to handle kernel NULL pointer dereference" |
| 异常地址 | "unable to handle kernel paging request"、"general protection fault" |
| OOM 内存耗尽 | "Out of memory and no killable processes"、"System is deadlocked on memory" |
| SysRq 触发 | "SysRq : Trigger a crashdump" |
| virsh dump | 无明显 panic 信息 |
👉 根据阶段二识别的 Panic 类型,只读取对应的场景分析文件(不要全部读取):
| Panic 类型 | 读取文件 |
|---|---|
| ------------ | --------- |
| Hung Task | references/reference/scenario_hung_task.md |
| Soft Lockup / Hard Lockup | references/reference/scenario_lockup.md |
| BUG_ON / NULL 指针 / 异常地址 | references/reference/scenario_bug_null_ptr.md |
| OOM 内存耗尽 | references/reference/scenario_oom_deadlock.md |
| SysRq 触发 / virsh dump | references/reference/scenario_sysrq_virsh.md(可能需要追加读取 lockup 或 hung task 场景文件) |
👉 分析过程中需要参考命令用法时,读取:references/reference/crash_commands.md
阶段三分析完成后,必须明确给出根因分类判定,决定后续流程走向:
| 根因分类 | 判定标准 | 后续流程 |
|---|---|---|
| ---------- | --------- | --------- |
| 内核缺陷 | 根因涉及内核代码 bug(如空指针解引用、竞态条件、逻辑错误、内核/内核模块内存泄漏等) | → 阶段四(查找社区 fix commit 及 bug issue)→ 阶段五 → 阶段六 → 阶段七 |
| 非内核缺陷 | 根因为业务配置问题、用户态程序行为、运维操作失误等(如 oom_score_adj 误配、用户进程内存泄漏、cgroup 配置不当、业务触发 SysRq 等) | → 跳过阶段四,直接进入 阶段五 → 阶段六 → 阶段七 |
判定原则:
⚡ 前置条件:仅当阶段三根因分类判定为"内核缺陷"或"存疑"时才执行此阶段。
如果阶段三已明确根因为非内核缺陷(如业务配置问题、用户态程序行为等),直接跳过此阶段,进入阶段五。若原因可能为内核缺陷不可跳过。
👉 必须完整读取详细步骤:references/phases/phase4_community_fix.md
核心要求摘要:
DISTRO_GIT_REPO 非空时必须执行):在用户提供的发行版 git 仓库中搜索修复 commit,通过 git tag --contains 确定哪个 tag 版本首次包含修复,并通过代码对比验证修复确实生效。这一步直接决定用户是"升级到发行版新版本"还是"自行反向移植"👉 必须完整读取详细步骤:references/phases/phase5_mitigation.md
核心要求:
分析报告需要用中文输出,保存为html格式,文件名按照crash_report_TIME.html格式命名,TIME为本地当前时间,精确到分钟,分析报告保存在vmcore文件所在目录。
必须使用 crash_report_generator.py 脚本生成报告(Markdown + 命令引用方案)。
👉 必须完整读取详细步骤:references/phases/phase6_report.md
核心要求摘要:
crash_report_generator.py 脚本生成,禁止直接手写 HTMLcrash_report_TIME.md → 调用脚本生成 crash_report_TIME.html(-l 参数指向 crash_cmd_log_TIME.jsonl)@cmd[] 引用 crash 命令输出,避免在 Markdown 中重复粘贴🔴 阶段六完毕后,调用 close_crash_session 关闭会话,释放 crash 进程资源。
mcp_get_tool_description(传入 toolRequests: [["aicrasher", "<工具名>"]])获取参数,再 mcp_call_tool(传入 serverName: "aicrasher", toolName: "<工具名>", arguments: "{...}")执行共 1 个版本