CtrlK
BlogDocsLog inGet started
Tessl Logo

windows-dmp-analysis

分析 Windows 崩溃转储文件(.dmp),诊断 MaaEnd 及其依赖项(MaaFramework、MXU)的崩溃。自动从 GitHub Releases 下载对应版本 PDB 符号,使用 minidump-stackwalk 解析堆栈轨迹并定位崩溃根因。当 issue 日志包或附件中发现 .dmp 文件,或用户要求分析 DMP/崩溃转储时使用。

70

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

Windows DMP Analysis

Scope

  • Windows minidump (.dmp) files from MaaEnd.
  • MaaEnd.dmp crashes almost always originate in MaaFramework (C++) or MXU (Rust/Tauri), not MaaEnd's Go code.
  • MaaEnd 自有 agent 是独立进程,崩溃时产生各自的 DMP:cpp-algo.exe.<pid>.dmpgo-service.exe.<pid>.dmp,符号来自 MaaEnd 自己的 Actions artifact(见 5.3 节,不随 release 发布)。
  • Only x86_64 covered below; for aarch64, substitute x86_64aarch64 in all download URLs.

Prerequisites

在本仓库的 issue-ai-analysis workflow 中会安装并确保 minidump-stackwalkdump_syms 可用(见 .github/workflows/issue-ai-analysis.yml)。如果你在本地复现或手动运行本流程,需要自行安装这些工具(可参考下文安装命令)。

Verify before proceeding:

which minidump-stackwalk && which dump_syms

If either is missing, install via:

curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall -y --no-confirm minidump-stackwalk dump_syms

Workflow

1. Obtain DMP

Download .dmp to .cache/dmp-analysis/issue-<number>/.

Sources:

  • Direct issue attachment (image/file link ending in .dmp)
  • Inside MaaEnd-logs-*.zip log package
WORK=".cache/dmp-analysis/issue-<NUMBER>"
mkdir -p "$WORK"
curl -L "<dmp_url>" -o "$WORK/MaaEnd.dmp"

2. Quick unsymbolicated analysis

minidump-stackwalk "$WORK/MaaEnd.dmp" 2>/dev/null

This gives without any symbols: OS info, exception type, module list with versions, raw stack frames.

Identify the crashing module from the exception address or the top stack frame.

3. Correlate DMP with logs

The DMP filename often contains the crashing PID (e.g. MaaEnd.exe.18188.dmp → PID 18188). Match this with maafw.log entries tagged [Px18188] to pinpoint the exact crashing session and its timeline.

4. Determine dependency versions

DMP module version info is frequently empty/unavailable. Prefer log and config sources:

PrioritySourceHow
1mxu-tauri.logmaa_init success, version: v5.x.x
2go-service.logclient_maafw_version / client_version in PI environment log
3Config files from logs packageinterface.json, maa_option.json
4Issue textUser-reported version
5Module list in stackwalk outputVersion column (often shows ?)

Record:

  • MaaEnd version (e.g. v0.8.0; used to fetch MaaEnd symbols in 5.3)
  • MaaFramework version (e.g. 5.9.2)
  • MXU version (e.g. 1.21.2)

5. Download PDB symbols

MaaFramework

MAA_VER="<version>"   # e.g. 5.9.2
curl -sL "https://github.com/MaaXYZ/MaaFramework/releases/download/v${MAA_VER}/MAA-win-x86_64-v${MAA_VER}.zip" \
  -o "$WORK/maa-fw.zip"
unzip -joq "$WORK/maa-fw.zip" 'symbol/*.pdb' -d "$WORK/pdb/"

PDB files inside symbol/:

PDBCorresponding Module
MaaFramework.pdbMaaFramework.dll — core pipeline runtime
MaaUtils.pdbMaaUtils.dll — utility library
MaaToolkit.pdbMaaToolkit.dll — toolkit
MaaWin32ControlUnit.pdbMaaWin32ControlUnit.dll — Win32 controller
MaaAdbControlUnit.pdbMaaAdbControlUnit.dll — ADB controller
MaaAgentServer.pdbMaaAgentServer.dll — agent server
MaaAgentClient.pdbMaaAgentClient.dll — agent client
MaaPiCli.pdbMaaPiCli.exe — CLI entry
OthersGamepadControlUnit, CustomControlUnit, NodeServer, Node

MXU

MXU_VER="<version>"   # e.g. 1.21.2
curl -sL "https://github.com/MistEO/MXU/releases/download/v${MXU_VER}/MXU-win-x86_64-v${MXU_VER}.zip" \
  -o "$WORK/mxu.zip"
unzip -joq "$WORK/mxu.zip" 'mxu.pdb' -d "$WORK/pdb/"

mxu.pdb is at the zip root (≈230 MB).

MaaEnd(自有符号)

MaaEnd 构建产出独立符号包,仅存 Actions artifact(默认保留 90 天),不随 release 发布。artifact 名即版本:MaaEnd-pdb-win-<arch>-<tag>,按 client_version 精确匹配:

MAAEND_VER="<version>"   # e.g. v0.8.0,与 interface.json 中 version 一致
# 1) 按版本号定位最新 artifact id(--paginate 翻页;同名多次构建时按 created_at 取最新;若返回空说明已过期)
ART_ID=$(gh api --paginate "repos/MaaEnd/MaaEnd/actions/artifacts?per_page=100" \
  --jq '.artifacts[] | select(.name == "MaaEnd-pdb-win-x86_64-'"${MAAEND_VER}"'") | [.id, .created_at] | @tsv' \
  | sort -k2 | tail -1 | cut -f1)
[ -n "$ART_ID" ] || { echo "symbol artifact expired or not found (90-day retention)"; exit 1; }
# 2) 下载并解压(GH_TOKEN 需有 actions:read 权限)
curl -sL -H "Authorization: Bearer $GH_TOKEN" \
  "https://api.github.com/repos/MaaEnd/MaaEnd/actions/artifacts/$ART_ID/zip" \
  -o "$WORK/maaend-pdb.zip"
unzip -joq "$WORK/maaend-pdb.zip" -d "$WORK/maaend-pdb/"

artifact 过期后无法再下载,需在对应版本提交上本地构建生成符号(python tools/build_and_install.py --cpp-algo)。注意:本地构建的 PDB GUID 与用户崩溃时的二进制不一致,只能近似符号化(函数级);且该命令只构建 cpp-algo,go-service 需另行执行 Go 构建。

包内内容:

文件对应模块用途
cpp-algo.pdbcpp-algo.exe(C++ 自定义识别/动作 agent,独立进程)dump_syms → .sym(与 MaaFramework PDB 流程相同)
go-service.exego-service.exe(Go agent,独立进程)Go 工具链不产出 PDB;该二进制为未剥离 DWARF 的精确构建产物,即调试符号本体
symbols-manifest.jsontag / commit / 上游版本,用于版本精确配对与校验
  • 崩溃模块为 cpp-algo.exe:按第 6 节流程转换 cpp-algo.pdb

  • 崩溃模块为 go-service.exe:minidump-stackwalk 无法直接符号化 Go 二进制。从无符号输出中取栈帧地址(格式 go-service.exe + 0xXXXX,模块内相对偏移 RVA),推荐用 gdb 解析(自动处理重定位,无需手工换算):

    gdb -batch -ex "core-file $WORK/MaaEnd.dmp" -ex "bt" "$WORK/maaend-pdb/go-service.exe"

    或用 go tool addr2line(注意:无 -e 参数,地址从 stdin 读取,且必须传完整虚拟地址)。Go amd64 PE 默认 image base 为 0x140000000,栈帧里的 RVA 需先换算成完整 VA 再传入:

    # 0xXXXX 替换为栈帧中的 RVA;换算后再解析(实测确认:传纯 RVA 会得到 ? / ?:0)
    printf '0x%x\n' $((0x140000000 + 0xXXXX)) | go tool addr2line "$WORK/maaend-pdb/go-service.exe"

6. Convert PDB → Breakpad .sym

mkdir -p "$WORK/symbols"
for pdb in "$WORK/pdb/"*.pdb; do
  name=$(basename "$pdb" .pdb)
  header=$(dump_syms "$pdb" 2>/dev/null | head -1)
  debug_id=$(echo "$header" | awk '{print $4}')
  dest="$WORK/symbols/${name}.pdb/${debug_id}"
  mkdir -p "$dest"
  dump_syms "$pdb" > "$dest/${name}.sym" 2>/dev/null
done

7. Full symbolicated stack walk

minidump-stackwalk "$WORK/MaaEnd.dmp" "$WORK/symbols" 2>/dev/null

Now stack traces include function names, source paths, and line numbers.

8. Analyze results

What to focus on

  1. Crashing thread — read stack top-down.
  2. Exception type:
    • EXCEPTION_ACCESS_VIOLATION (0xC0000005) — null/dangling pointer, use-after-free
    • EXCEPTION_STACK_OVERFLOW (0xC00000FD) — infinite recursion or oversized stack allocation
    • EXCEPTION_ILLEGAL_INSTRUCTION (0xC000001D) — corrupted code or wrong CPU feature
    • STATUS_STACK_BUFFER_OVERRUN (0xC0000409) — NOT always a real buffer overrun. This is the Windows fast-fail mechanism. Check the first exception parameter:
      • 0x7 = FAST_FAIL_FATAL_APP_EXIT — means std::terminate() / abort() was called, typically from an unhandled C++ exception (e.g. cv::Exception from OpenCV receiving an empty cv::Mat). This is the most common MaaEnd crash pattern.
      • 0x2 = FAST_FAIL_RANGE_CHECK_FAILURE
      • Other values: see FAST_FAIL codes
    • EXCEPTION_BREAKPOINT (0x80000003) — deliberate crash / assertion failure / Rust panic
  3. Faulting module ownership:
    • Maa*.dll → MaaFramework → upstream MaaXYZ/MaaFramework
    • mxu.exe → MXU → upstream MistEO/MXU
    • cpp-algo.exe → MaaEnd 自有 C++ agent → 按 5.3 节从 Actions artifact 获取对应 tag 的符号包
    • go-service.exe → MaaEnd 自有 Go agent → 同上,用包内精确二进制 + addr2line/gdb
    • onnxruntime_maa.dll, opencv_world4_maa.dll, fastdeploy_ppocr_maa.dll → third-party inference/vision
    • DirectML.dll → DirectX ML runtime
    • ViGEmClient.dll → virtual gamepad
    • ntdll.dll, KERNELBASE.dll, ucrtbase.dll → OS / CRT; look at the caller frames above
    • If crash address is in ucrtbase.dll with code 0xC0000409, the real crash site is in the caller frames, not ucrtbase itself
  4. Recurring patterns:
    • Multiple threads crashing or deadlocked
    • Stack corruption (truncated / nonsensical frames)
    • Heap corruption indicators (RtlReportCriticalFailure, RtlpLogHeapFailure)
    • Rust panic (rust_begin_unwind, core::panicking::*)

9. Cross-reference with source

If the crash is in MaaFramework:

git clone --depth 1 --branch "v${MAA_VER}" \
  https://github.com/MaaXYZ/MaaFramework.git ".cache/upstream-src/MaaFramework"

If the crash is in MXU:

git clone --depth 1 --branch "v${MXU_VER}" \
  https://github.com/MistEO/MXU.git ".cache/upstream-src/MXU"

Look up the function and line from the symbolicated stack trace in the cloned source.

Output Format

## DMP 分析结果

- DMP 文件:`<filename>`
- 操作系统:`<OS version>`
- 异常类型:`<EXCEPTION_*>`
- 崩溃模块:`<module_name>` (版本 `<version>`)
- 崩溃函数:`<symbolicated function name>`

## DMP 崩溃分析

### 崩溃堆栈(crashing thread)

<crashing thread 的全部有效符号化堆栈帧;如堆栈被截断/损坏,请在此说明原因>

### 关键模块版本

| Module           | Version |
| ---------------- | ------- |
| mxu.exe          | ...     |
| MaaFramework.dll | ...     |
| ...              | ...     |

### 根因判断

- 崩溃归属:MaaFramework / MXU / 第三方依赖 / 未知
- 分析:...
- 置信度:高 / 中 / 低

### 建议

- 对用户的建议(升级、绕过方案等)
- 对开发者的建议(上游报告、修复方向)

Cleanup

After analysis is complete:

rm -rf ".cache/dmp-analysis/issue-<NUMBER>"
Repository
MaaEnd/MaaEnd
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.