本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
Crashpad是Chromium内核提供的进程崩溃信息处理工具。在应用使用Web组件导致进程(主要是Web渲染进程)崩溃时,Crashpad会在应用主进程沙箱目录写入minidump文件(后缀为.dmp),记录进程崩溃的原因、线程信息、寄存器信息等关键数据,帮助分析和定位崩溃问题。
特点
-
自动记录:进程崩溃时自动生成dump文件
-
信息全面:包含崩溃原因、线程栈、寄存器状态等
-
定位精准:可结合符号文件定位到源码位置
二、Crashpad原理
Web渲染进程崩溃
↓
Crashpad捕获崩溃信息
↓
生成minidump文件(.dmp)
↓
写入应用沙箱目录
↓
获取并解析
↓
定位崩溃源码位置
三、dmp文件存储位置
文件路径
当Web组件相关进程崩溃后,dmp文件会生成在应用主进程沙箱目录下:
/data/storage/el2/log/crashpad
文件格式
-
格式:二进制格式
-
后缀:.dmp
-
命名:UUID格式(如:b678e0b5-894b-4794-9ab3-fb5d6dda06a3.dmp)
文件内容
dmp文件记录了以下关键信息:
-
进程崩溃的原因
-
崩溃时的线程信息
-
CPU寄存器状态
-
调用栈信息
-
内存片段
四、获取dmp文件
访问应用沙箱
需要通过Native方式访问应用沙箱获取dmp文件。具体实现参考:
文件访问示例(C++)
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
// 获取crashpad目录路径
std::string getCrashpadPath() {
// 沙箱基础路径
const char* basePath = "/data/storage/el2/log";
std::string crashpadPath = std::string(basePath) + "/crashpad";
return crashpadPath;
}
// 列出所有dmp文件
std::vector<std::string> listDmpFiles() {
std::vector<std::string> dmpFiles;
std::string crashpadPath = getCrashpadPath();
try {
for (const auto& entry : std::filesystem::directory_iterator(crashpadPath)) {
if (entry.path().extension() == ".dmp") {
dmpFiles.push_back(entry.path().string());
std::cout << "找到dmp文件: " << entry.path().string() << std::endl;
}
}
} catch (const std::exception& e) {
std::cerr << "访问目录失败: " << e.what() << std::endl;
}
return dmpFiles;
}
// 复制dmp文件到可访问位置
bool copyDmpFile(const std::string& sourcePath, const std::string& destPath) {
try {
std::filesystem::copy_file(sourcePath, destPath,
std::filesystem::copy_options::overwrite_existing);
std::cout << "文件已复制到: " << destPath << std::endl;
return true;
} catch (const std::exception& e) {
std::cerr << "复制文件失败: " << e.what() << std::endl;
return false;
}
}
五、解析dmp文件
1. 获取minidump_stackwalk工具
minidump_stackwalk由breakpad项目源码编译得到。
源码仓库:
https://chromium.googlesource.com/breakpad/breakpad
编译方法(Linux环境):
# 克隆仓库
git clone https://chromium.googlesource.com/breakpad/breakpad
cd breakpad
# 配置编译
./configure
make
# 编译后的工具位于 src/processor/ 目录
# minidump_stackwalk 可执行文件
2. 使用minidump_stackwalk解析
基本命令:
./minidump_stackwalk [dmp文件路径] > [输出文件]
示例:
./minidump_stackwalk b678e0b5-894b-4794-9ab3-fb5d6dda06a3.dmp > parsed_stacktrace.txt
3. 输出示例
Crash reason: SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: 12 seconds
Thread 0 (crashed)
0 libweb_engine.so + 0x2e0b340
x0 = 0x00000006a5719ff8 x1 = 0x000000019a5a28c0
x2 = 0x0000000000020441 x3 = 0x00000000000001b6
x4 = 0x0000000000000018 x5 = 0x0000000000008065
x6 = 0x0000000000008065 x7 = 0x63ff686067666d60
x8 = 0x0000000000000000 x9 = 0x5f129cf9e7bf008c
x10 = 0x0000000000000001 x11 = 0x0000000000000000
x12 = 0x000000069bfcc6d8 x13 = 0x0000000009a1746e
x14 = 0x0000000000000000 x15 = 0x0000000000000000
x16 = 0x0000000690df4850 x17 = 0x000000010c0d47f8
x18 = 0x0000000000000000 x19 = 0x0000005eea827db8
x20 = 0x0000005eea827c38 x21 = 0x00000006a56b1000
x22 = 0x00000006a8b85020 x23 = 0x00000020002103c0
x24 = 0x00000006a56b8a70 x25 = 0x0000000000000000
x26 = 0x00000006a8b84e00 x27 = 0x0000000000000001
x28 = 0x0000000000000000 fp = 0x0000005eea827c10
lr = 0x000000069fa4b33c sp = 0x0000005eea827c10
pc = 0x000000069fa4b340
Found by: given as instruction pointer in context
1 libweb_engine.so + 0x2e0b338
fp = 0x0000005eea827d80 lr = 0x000000069fa48d44
sp = 0x0000005eea827c20 pc = 0x000000069fa4b33c
Found by: previous frame's frame pointer
2 libweb_engine.so + 0x2e08d40
fp = 0x0000005eea827e50 lr = 0x00000006a385cef8
sp = 0x0000005eea827d90 pc = 0x000000069fa48d44
Found by: previous frame's frame pointer
3 libweb_engine.so + 0x6c1cef4
fp = 0x0000005eea828260 lr = 0x00000006a0f11298
sp = 0x0000005eea827e60 pc = 0x00000006a385cef8
…
4. 解析结果
| Crash reason | SIGSEGV /SEGV_MAPERR | 导致进程崩溃的信号,此处为段错误 |
| Crash address | 0x0 | 崩溃时访问的内存地址 |
| Process uptime | 12 seconds | 进程运行时间 |
| Thread X (crashed) | Thread 0 (crashed) | 发生崩溃的线程 |
| 寄存器信息 | x0-x28, fp, lr, sp, pc | CPU寄存器状态 |
| 调用栈 | libweb_engine.so + 0x2e0b340 | 各层调用栈,包含SO偏移地址 |
六、定位崩溃源码位置
使用llvm-addr2line工具
llvm-addr2line工具链位于SDK中,可以将SO偏移地址转换为源码位置。
基本命令:
./llvm-addr2line -Cfpie [SO文件] [偏移地址]
参数说明:
-
-C:反修饰C++符号名
-
-f:显示函数名
-
-p:显示每行信息
-
-i:内联函数展开
-
-e:指定可执行文件
示例:
./llvm-addr2line -Cfpie libweb_engine.so 0x2e0b340
输出示例:
WebEngine::RenderFrameImpl::OnMessageReceived(IPC::Message const&) at /path/to/source/render_frame_impl.cc:1234
七、完整操作
步骤1:应用崩溃后获取dmp文件
# 进入应用沙箱crashpad目录
cd /data/storage/el2/log/crashpad
# 查看生成的dmp文件
ls -la *.dmp
# 输出: b678e0b5-894b-4794-9ab3-fb5d6dda06a3.dmp
步骤2:将dmp文件导出到开发机
# 使用hdc命令导出文件
hdc file recv /data/storage/el2/log/crashpad/b678e0b5-894b-4794-9ab3-fb5d6dda06a3.dmp ./
步骤3:使用minidump_stackwalk解析
# 解析dmp文件
./minidump_stackwalk b678e0b5-894b-4794-9ab3-fb5d6dda06a3.dmp > crash_analysis.txt
# 查看解析结果
cat crash_analysis.txt
步骤4:定位源码位置
# 从解析结果中找到关键偏移地址(如0x2e0b340)
# 使用llvm-addr2line转换
./llvm-addr2line -Cfpie libweb_engine.so 0x2e0b340
步骤5:分析崩溃原因
根据解析结果判断崩溃类型:
| SIGSEGV | 段错误,访问非法内存地址 |
| SIGABRT | 进程主动中止 |
| SIGFPE | 算术异常(除零等) |
| SIGILL | 非法指令 |
网硕互联帮助中心








评论前必须登录!
注册