Logo Vincent
返回文章列表

Electron-开发实践:crash上报及解析

Electron
Electron-开发实践:crash上报及解析

【前言】

electron开发实践中,crash的上报不可避免,

electron中可以通过crashReporter来上报crash,

https://www.electronjs.org/docs/latest/api/crash-reporter

而处理crash使用的是crashpad,有兴趣的可以继续研究下,

https://chromium.googlesource.com/crashpad/crashpad/+/refs/heads/main/README.md

【crashReporter】

通过start方法启动上报,

start需要尽早的调用,

例如在app.on(‘ready’)前

// crash reporter
const { crashReporter } = require('electron');

/**
 * start方法
 */
crashReporter.start({
  // 要上报的服务器地址
  submitURL: 'https://your-domain.com/url-to-submit',

  // 产品名称
  productName: 'x',

  // 是否压缩,默认true,如果开启会上传gzip,服务器要处理一下
  compress: false,

  // 是否限制频次,默认为false,如果开启每小时上传1次
  rateLimit: false,

  // 是否上传到服务器,默认为true,如果关闭只在本地生成crash文件
  uploadToServer: true,

  // 是否禁止系统crash处理,默认为false
  ignoreSystemCrashHandler: false,

  // 携带的参数,extra中的参数只有主进程崩溃会携带
  extra: {
    userId: 'xxx',
  },

  // 携带的参数,globalExtra中的参数所有进程崩溃都会携带
  globalExtra: {
    userId: 'xxx',
  },
});

通过addExtraParameter来添加携带的参数

crashReporter.addExtraParameter(key, value);

通过crash方法来产生crash,进行测试

process.crash();

如果需要子进程单独上报,可以使用如下方法

process.crashReporter.start(options);

【服务端处理上报】

这里服务端使用qiao-z这个框架来演示,

文档: https://qiao-z.vincentqiao.com/#/

服务端:安装依赖

npm i qiao-z qiao-z-upload

服务端:app.js

// qz
const qz = require('qiao-z');

// app
const app = qz({
  upload: require('qiao-z-upload'),
});

// listen
app.listen(9001);

服务端:CrashController.js,qiao-z会自动扫描Controller.js结尾的文件,并注册路由

// fs
const { renameSync } = require('fs');

// path
const { resolve } = require('path');

/**
 * crash controller
 */
module.exports = (app) => {
  // crash
  app.post('/crash', async (req, res) => {
    try {
      // fields
      const fields = req.body.fields;
      console.log('fields: ', fields);

      // file info
      const fileInfo = req.body.files.upload_file_minidump;
      const tmpPath = fileInfo.filepath;
      const destPath = resolve(__dirname, fileInfo.originalFilename);
      renameSync(tmpPath, destPath);

      // return
      res.send('crash success');
    } catch (e) {
      console.log(e);
      res.send('crash failed');
    }
  });
};

服务端:启动服务

node app.js

electron:设置crashReporter的submitURL

    submitURL: 'http://localhost:9001/crash',

electron:crashReporter启动后设置4s后的crash

// report
crashReporter.start(options);

// crash
setTimeout(() => {
  process.crash();
}, 4000);

服务端:查看效果

1.dmp文件

2.获取到的上报信息

这里可以看到,处理一些基础信息,已经上报了globalExtra中的userId信息

【解析dmp文件】

如上,已经获取到electron应用crash的dmp文件了,

那么,如何解析dmp文件呢,稍微比较复杂

安装depot_tools

breakpad依赖于depot_tools

|— 首先clone项目

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

|— 然后设置path

export PATH=/path/to/depot_tools:$PATH

安装breakpad

|— 创建文件夹

mkdir breakpad && cd breakpad

|— 下载breakpad

fetch breakpad
cd src

|— 构建breakpad

./configure && make

|— 安装命令

make install

下载electron symbols文件

|— 下载地址: https://github.com/electron/electron/releases

|— 找到对应操作系统和electron版本的symbols.zip文件并下载,例如我本地是22.0.0版本

使用breakpad解析dmp文件

|— 使用breakpad的minidump_stackwalk命令解析dmp文件

minidump_stackwalk -s PATH_TO_DUMP PATH_TO_electron.breakpad.sym

上面两个路径,

第一个是dmp路径,例如:

dmp/e66fdb11-043e-4f4f-ac24-8a473d54e0b3.dmp

第二个是sym路径,例如:

electron-v22.0.0-darwin-arm64-symbols/breakpad_symbols/chrome_crashpad_handler/chrome_crashpad_handler.sym

执行命令后解析效果如下

【electron-minidump】

上面解析完后的文件基本没有可读性,

是因为只使用的chrome对应的符号文件进行解析,

如果把一个dmp文件比喻为一个构建后的js文件,

如果想解析js文件所有的源码,

需要知道这个js引用的所有npm包的源码。

依次类推,解析一个dmp文件需要用到很多符号表,

比如electron的,electron渲染进程的,chrome的等等,

这里推荐一个工具进行解析: https://www.npmjs.com/package/electron-minidump

简单总结这个工具的解析方法

1.下载dmp文件对应的所有需要的sym文件

2.使用这些sym文件解析dmp文件

使用方式如下:

npx electron-minidump -f /path/to/your/dmp/file

效果如下

下载sym文件:

可以看到解析一个dmp文件,

需要下载对应的607个sym文件,

解析后内容如下:

可以看到这次解析后已经可以看到具体的异常堆栈了

【第三方方案】

上述本地解析dmp文件比较麻烦,

是否有比较方便的方案,

确实有,但是大部分收费,

例如: https://sentry.io/welcome/

【总结】

1. electron crashReporter如何使用

2. 服务端如何接收crash上报

3. 本地如何解析接收到的dmp文件

4. 其他解析方案

© 2026 Vincent. 保留所有权利。