用 dump_syms + minidump-stackwalk 从 minidump 还原调用栈
December 25, 2024About 1 min
用 dump_syms + minidump-stackwalk 从 minidump 还原调用栈
线上崩溃通常只回收到一个体积很小的 .dmp(minidump),里面只有崩溃时刻的线程栈、寄存器和模块列表,没有符号。要还原出可读的函数调用栈,需要两样东西:从 .pdb 抽出来的 Breakpad 符号文件,和一个能拿符号去解析 dump 的 walker。这套工具链跨平台、不依赖 Visual Studio,很适合放进 CI 或崩溃收集服务。
- dump_syms:读
.pdb(或 Linux 的 DWARF、macOS 的 dSYM),产出 Breakpad 格式的.sym符号文件。 - minidump-stackwalk:拿符号目录去解析
.dmp,打印出带函数名/行号的调用栈。
两者都来自 Breakpad / Crashpad 生态;现在 minidump-stackwalk 也有 Rust 重写版(rust-minidump),可以直接 cargo install minidump-stackwalk 拿到,dump_syms 同样有 Rust 版(cargo install dump_syms)。
1. 从 pdb 生成符号
dump_syms -s <symbol_store_path> test.pdb
-s 指定符号库(symbol store)路径,dump_syms 会按 模块名/调试ID/模块名.sym 的层级结构把 .sym 落到这个目录里。建议每次出包时把对应的 .pdb 都 dump 一份进同一个符号库,和构建产物一起归档——崩溃回来时才有对得上的符号。
2. 从 dump 还原调用栈
minidump-stackwalk --symbols-path <symbol_path> --brief test.dmp
--symbols-path 指向上一步的符号库,--brief 输出精简的调用栈。去掉 --brief 会打印更详细的线程、模块、寄存器信息。
关键点是符号库里的调试 ID 必须和出事那个二进制完全匹配——版本对不上就解析不出函数名,只剩地址。所以发布流程里要把「构建 → dump 符号 → 归档」绑在一起做。