在 CentOS 中编译 breakpad

在解析 Electron 应用 Crash 产生的 dump 文件时,需要使用 breakpad 提供的 minidump_stackwalk 工具。
直接从 NPM 下载的 minidump 需要较高版本的 glibc。由于一些原因,我需要在 CentOS 7 环境中运行 minidump_stackwalk,而 CentOS 7 默认的 glibc 版本是 2.17,不能更满足要求,所以需要自行编译 breakpad。
这里记录了一下在 CentOS 7 中编译 breakpad 的过程。

准备编译环境

启动 CentOS 7 环境

可以通过虚拟机或者 Docker 的方式来获取 CentOS 7 环境,这里为了方便就直接使用 Docker:

# 启动 CentOS 7 的容器
docker run -it --rm centos:7 bash

修改软件源

容器启动后,需要先修改容器中的软件源,否则无法下载需要用到的依赖,这里使用的是 Tsinghua Open Source Mirror

# 修改软件源地址
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
    -e "s|^#baseurl=http://mirror.centos.org/centos/\$releasever|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009|g" \
    -i.bak \
    /etc/yum.repos.d/CentOS-*.repo

# 更新软件缓存
yum makecache

安装编译工具

编译 breakpad 需要较新版本的 GCC 编译器,这里通过 SCL 来安装,首先安装 SCL:

# 安装 SCL
yum install -y centos-release-scl

# 修改 SCL 软件源地址
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
    -e "s|^# \?baseurl=http://mirror.centos.org/centos/7|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009|g" \
    -i.bak \
    /etc/yum.repos.d/CentOS-SCLo-*.repo

# 更新软件缓存
yum makecache

然后再安装 GCC 编译器:

# 安装 GCC 编译器
yum install -y git zlib-devel devtoolset-11-gcc-c++

# 启用 GCC 编译器
scl enable devtoolset-11 bash

获取源代码

首先准备一个用于存放编译项目用到的文件夹:

# 准备编译目录
mkdir -p ~/breakpad-compile

通过 Git 仓库来获取需要用到的源代码:

cd ~/breakpad-compile

# 获取 breakpad 源代码
git clone https://github.com/google/breakpad.git ./breakpad

# 获取 linux-syscall-support 源代码,包含 breakpad 依赖的头文件
git clone https://chromium.googlesource.com/linux-syscall-support ./breakpad/src/third_party/lss

开始编译

完整编译

在准备好源代码后,还不能直接开始编译,经过测试需要回退代码到 commit 7ea7ded187b4d739239f3ab7082fcd5a2ccc1eaa 才能编译通过。
主要原因是最新代码中使用到的 SHF_COMPRESSED 在我们的编译环境中没有定义,直接编译会报错:

cd ~/breakpad-compile/breakpad

# 全量编译需要回退到这个版本,避免使用 SHF_COMPRESSED
git reset --hard 7ea7ded187b4d739239f3ab7082fcd5a2ccc1eaa

回退完成后即可开始编译:

cd ~/breakpad-compile/breakpad

# 开始编译
./configure && make

部分编译

如果不想回退代码,也可以只编译部分工具,经测试以下工具可以直接编译:

  • minidump_dump
  • minidump_stackwalk

测试时的最新 commit 是 1db382f0dabe2d17f49956066286e4bf15482b5a

编译方式如下:

cd ~/breakpad-compile/breakpad

# 只编译 src/processor/minidump_dump
./configure && make src/processor/minidump_dump

# 只编译 minidump_stackwalk
./configure && make src/processor/minidump_stackwalk

CentOS 6 的编译方式

如果还需要在 CentOS 6 下进行编译,只需要按照以下步骤进行即可:

# 修改软件源地址
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
    -e "s|^#baseurl=http://mirror.centos.org/centos/\$releasever|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/6.10|g" \
    -i.bak \
    /etc/yum.repos.d/CentOS-*.repo

# 更新软件缓存
yum makecache

# 安装 SCL
yum install -y centos-release-scl

# 修改 SCL 软件源地址
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
    -e "s|^# \?baseurl=http://mirror.centos.org/centos/6|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/6.10|g" \
    -i.bak \
    /etc/yum.repos.d/CentOS-SCLo-*.repo

# 更新软件缓存
yum makecache

# 安装 GCC 编译器
yum install -y git zlib-devel devtoolset-9-gcc-c++

# 启用 GCC 编译器
scl enable devtoolset-9 bash

# 准备编译目录
mkdir -p ~/breakpad-compile

cd ~/breakpad-compile

# 获取 breakpad 源代码
git clone https://github.com/google/breakpad.git ./breakpad

# 获取 linux-syscall-support 源代码,包含 breakpad 依赖的头文件
git clone https://chromium.googlesource.com/linux-syscall-support ./breakpad/src/third_party/lss

cd ~/breakpad-compile/breakpad

# 全量编译需要回退到这个版本,避免使用 O_TMPFILE, SHF_COMPRESSED
git reset --hard 7ea7ded187b4d739239f3ab7082fcd5a2ccc1eaa

# 开始编译
./configure && make

# 只编译 src/processor/minidump_dump 可以直接编译
./configure && make src/processor/minidump_dump

# 只编译 minidump_stackwalk 需要回退到这个版本,避免使用 O_TMPFILE
git reset --hard f6178140175800cc6385a151e7f23d6e5c4968ca
./configure && make src/processor/minidump_stackwalk