mcpField
S
symbolicate-crash-dump

symbolicate-crash-dump

github.com/microsoft开发194.4k57 次安装今天更新
代码仓库

关于 symbolicate-crash-dump

symbolicate-crash-dump 介绍如何使用 `electron-minidump` 将 VS Code 原生 `.dmp` 文件转换为可读回溯。该指南面向 VS Code 团队成员,涵盖符号匹配、崩溃归因及远程 Linux 扩展主机崩溃分析。

主要功能

  1. 01符号化原生崩溃转储
  2. 02按构建版本和调试 ID 匹配符号
  3. 03判断崩溃模块与进程
  4. 04比较重复崩溃特征
  5. 05使用 gdb 分析远程 Linux 核心转储

适用场景

  1. 01分析 VS Code 原生崩溃
  2. 02定位缺失的符号文件
  3. 03判断崩溃所属模块
  4. 04调查远程扩展主机崩溃

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/vscode --skill symbolicate-crash-dump

安装后在 Claude Code 中输入/symbolicate-crash-dump确认已加载。

详细介绍

符号化崩溃转储文件

使用 electron-minidump,将原生 VS Code 崩溃转储文件(.dmp)转换为包含方法名称的可读回溯信息。

仅限 VS Code 团队成员。 内部 Electron、Insiders 和 Stable 版本的符号文件存放在一个相邻的私有发布仓库中。必须使用 macOS 或 Linux 设备——electron-minidump 无法在 Windows 上运行。

前提条件

  • 崩溃转储文件(*.dmp)。如果还没有,请参阅下方的创建崩溃报告。
  • 全局安装 electron-minidump:
    npm install -g electron-minidump
    
  • 对于 Insiders/Stable 符号,需要经过身份验证且有权访问私有 microsoft/vscode-electron-prebuilt 仓库的 GitHub CLI(gh auth status)。

操作步骤

1. 运行初步符号化

此操作会生成或刷新 electron-minidump 缓存,并告知你仍缺少哪些符号。

electron-minidump crash-file.dmp > symbolicated-output.log

检查 symbolicated-output.log。查看回溯信息顶部的栈帧:如果某个栈帧列出了模块(例如 Electron Framework),但后面没有方法名称,则需要该模块的符号。

临时下载错误时请重试。 electron-minidump 会从公共符号服务器下载符号,因此运行时可能会遇到临时网络错误(例如 failed to download ... (code 56) 或 (code 28))。已成功下载的符号会缓存,因此只需重新运行相同命令,就能从中断处继续。预期需要重试几次:

for i in 1 2 3 4 5; do
    electron-minidump crash-file.dmp > symbolicated-output.log && break
    sleep 3
done
2. 获取相应的符号文件

根据导致崩溃的版本,选择符号来源:

发生崩溃的版本符号文件来源
Insiders / Stable(内部 Electron)microsoft/vscode-electron-prebuilt releases
Code - OSS(OSS Electron)electron/electron releases

microsoft/vscode-electron-prebuilt 是一个私有仓库——因此此流程仅限团队成员使用。未通过身份验证时,普通浏览器或 curl 链接会返回 404;请改用经过身份验证的 GitHub CLI 下载资源(gh auth status 应显示你已登录):

# List releases (tagged by Electron version) to find the right tag:
gh release list --repo microsoft/vscode-electron-prebuilt

# Download just the symbol zip you need:
gh release download v42.5.0-14525058 \
    --repo microsoft/vscode-electron-prebuilt \
    --pattern "stable-symbols-v42.5.0-win32-x64.zip"

发布版本使用 Electron 版本标记,而非 VS Code 版本,因此请先找出发生崩溃的 VS Code 版本所使用的 Electron 版本。该版本 .npmrc 中的 target= 就是所需信息(例如 git show 1.128.0:.npmrc),它与 package.json 中的 electron 开发依赖项一致。然后根据质量、平台和架构选择匹配的符号 zip 文件——例如,Electron 42.5.0 上发生崩溃的 Stable Windows x64 版本需要 stable-symbols-v42.5.0-win32-x64.zip(Insiders 版本请使用 insiders-symbols-…)。Code - OSS 符号来自公开的 electron/electron releases,无需特殊权限即可下载。

这些 zip 文件较小,且仅包含部分符号。 *-symbols-*.zip 通常只包含少数几个第一方模块——Windows 上的 electron.exe.sym、libEGL.dll.sym、libGLESv2.dll.sym(其他平台上则包含对应文件)。回溯信息中出现的许多模块——尤其是 runtime.node 和任何操作系统或第三方 DLL——都不在这些 zip 文件中。通常无法使用公开符号为 runtime.node 栈帧进行符号化;如果崩溃发生在第三方模块中,应根据模块名称判断,而不要期待每个栈帧都有方法名称(请参阅阅读结果)。

3. 将 .sym 文件复制到 electron-minidump 缓存

缓存位于:

"$(npm root -g)/electron-minidump/cache/breakpad_symbols"

Breakpad 使用 <module>.pdb/<debug-id>/<module>.sym 作为符号键,其中 <debug-id> 必须与转储文件和符号压缩包中的值完全一致——即使是同一版本,只要压缩包来自不同的流水线运行,其 ID 就会不同,因此不会被使用。完成初步检查后,缓存中已经为每个所需模块创建了一个(空)目录,你必须匹配其名称和哈希值:

CACHE="$(npm root -g)/electron-minidump/cache/breakpad_symbols"
# The debug-id electron-minidump wants for a given module:
ls "$CACHE/electron.exe.pdb"     # e.g. DD081533CD7E33A44C4C44205044422E1

解压下载的符号文件,并确认压缩包中存在相同模块和哈希值,然后再将其复制到缓存中。压缩包内部的布局同样是 <module>.pdb/<debug-id>/<module>.sym。

示例(Windows:随附的主二进制文件是 Code.exe,但其符号来自 electron.exe.sym):

# Unzip somewhere, e.g. ~/stable-symbols/
unzip stable-symbols-v42.5.0-win32-x64.zip -d ~/stable-symbols

# Only copy if the debug-id matches what the cache expects.
# Keep the tilde outside quotes so it expands to your home directory:
HASH=DD081533CD7E33A44C4C44205044422E1
cp ~/stable-symbols/symbols/electron.exe.pdb/"$HASH"/electron.exe.sym \
   "$CACHE/electron.exe.pdb/$HASH/"

在 macOS 上,对应的模块是 Electron Framework(Electron Framework/<hash>/Electron Framework.sym)。对于初步检查报告缺少方法名的其他模块,也重复此操作——但前提是压缩包中确实包含与其哈希值匹配的 .sym 文件。

如果不存在哈希值匹配的符号文件,就无法获取该模块的方法名——这在官方发布的 Stable/Insiders 版本中很常见,因为公开的预构建压缩包里可能没有其准确的 electron.exe/Code.exe 哈希值;runtime.node 也常见这种情况。请改为根据模块和进程判断崩溃原因(见阅读结果);这通常足以找出第三方责任方。

4. 重新运行符号化
electron-minidump crash-file.dmp > symbolicated-output.log

symbolicated-output.log 中的回溯现在应该已附带方法名。如果仍有一些栈帧没有方法名,请返回步骤 2,为仍缺少符号的模块重复操作。

阅读结果

获得符号化的回溯后,请回答两个问题,以确定根本原因:

哪个模块导致了崩溃?

查看崩溃线程的顶层栈帧(标记为 (crashed))及其模块名称:

  • 如果是 VS Code / Electron 模块——Code.exe、runtime.node、Electron Framework、libnode、libffmpeg、V8 栈帧——故障很可能出在产品或 Electron 内部。
  • 如果是第三方 / 操作系统模块——注入进程的杀毒软件、VPN、代理或 shell 扩展 DLL——崩溃几乎肯定由该软件而非 VS Code 导致。注入的 DLL 通常会与 runtime.node/V8 栈帧交错出现,因为它们会挂钩运行时。

请在磁盘上找到该模块的加载位置,以确认它属于第三方。在 Windows 上,转储文件中的 strings 通常会显示完整路径,例如 DLL 位于 C:\WINDOWS\system32\ 或供应商目录下,而非 VS Code 安装目录:

strings -a crash-file.dmp | grep -i "<SuspectModule>" | sort -u
哪个进程发生了崩溃?

进程类型可以告诉你崩溃的是主进程、渲染器/窗口,还是扩展宿主。在较新的 Electron 中,扩展宿主运行在 Node 实用程序进程内,因此此类崩溃会显示为 node.mojom.NodeService 实用程序进程,而不是名称真的叫“扩展宿主”的进程:

strings -a crash-file.dmp | grep -oiE "utility-sub-type=[a-zA-Z0-9._-]+|node\.mojom\.[A-Za-z]+|--type=[a-z-]+" | sort -u
标记进程
node.mojom.NodeService / utility-sub-type=node.mojom.NodeService扩展宿主(Node 实用程序进程)
--type=renderer工作台窗口(渲染器)
--type=gpu-processGPU 进程
(no --type)主进程

请将此信息与报告中的症状进行对照(例如,“扩展宿主崩溃循环”应对应 NodeService 实用程序进程崩溃)。

如果有多个转储文件,请分别对其进行符号化,并比较崩溃原因和顶层栈帧——多个转储文件中出现相同的特征,表明原因一致且可复现。

创建崩溃报告

如果你还没有 .dmp 文件,可以使用 --crash-reporter-directory 选项生成一个:

  1. 关闭所有 VS Code 实例。
  2. 在命令行中运行 code --crash-reporter-directory <absolute-path>(Insiders 版本请使用 code-insiders)。
  3. 执行导致崩溃的操作。
  4. 在该文件夹中查找 *.dmp 文件。

只有当你拥有与构建版本匹配的符号文件时,才能对崩溃进行符号化。Insiders/Stable 版本的崩溃需要内部 Electron 符号文件;本地源代码构建版本(Code - OSS)的崩溃需要 OSS Electron 符号文件。

远程扩展宿主崩溃(Linux,gdb)

远程服务的扩展宿主发生原生崩溃时,会使用核心转储和 gdb,而非 electron-minidump:

  1. 启动服务前,允许生成核心转储:ulimit -c unlimited。
  2. 重现崩溃。通过 coredumpctl 获取核心转储,或从 /proc/sys/kernel/core_pattern 中指定的路径获取。
  3. 在 gdb 中加载核心转储并捕获输出:
    gdb -se <path-to-vscode-server>/node -c <path-to-core-file>
    
    然后运行以下命令并收集输出:
    set pagination off
    info sharedlibrary
    info registers
    bt full
    disassemble
    

提示

  • 请勿将 crash-file.dmp 和 symbolicated-output.log 放入仓库——它们是临时产物。
  • 缓存路径是动态的;请始终使用 $(npm root -g) 解析路径,而不要硬编码主目录。
  • Breakpad 根据精确的 debug-id 匹配符号,而非版本名称。如果添加符号后仍缺少方法名,请确认复制的 .sym 与缓存目录所需的哈希完全一致,并再次检查符号 zip 的质量(stable/insiders)、平台(win32/darwin/linux)和架构(x64/arm64)。
  • 并非所有帧都能进行符号化。runtime.node 和第三方/OS 模块通常没有公开符号;通常只需识别发生崩溃的模块和进程,就足以找到根本原因。

评论

支持 Markdown