网易首页 > 网易号 > 正文 申请入驻

学会这个绝招,让 C++ 崩溃无处可逃!

0
分享至

作者 | Waleon

来源 | 高效程序员

Breakpad 是 Google 用 C++ 编写的一个开源、跨平台的崩溃报告系统,它支持 Windows、Linux 和 macOS,并提供了一个上传器,可以在进程崩溃时向一个配置好的 URL 提交 minidump 文件。

目前,有很多大型项目都在使用 Breakpad,例如:Google Chrome、Firefox、Google Picasa、Camino、Google Earth 等。

  • 主页:https://chromium.googlesource.com/breakpad/breakpad/

  • 文档:https://chromium.googlesource.com/breakpad/breakpad/+/HEAD/docs

  • GitHub 地址:https://github.com/google/breakpad

工作原理

BreakPad 工作原理:

其中,包含了三个主要组件:

  • Breakpad client:是一个库(即:libbreakpad_client.a),将来要集成到我们的程序中。用于写 minidump 文件,捕获当前线程的状态,以及可执行文件/共享库的标识。

  • Breakpad 符号转储工具:是一个程序(即:dump_syms),用于读取由编译器产生的调试信息,并以 Breakpad 自己的格式生成一个符号文件。

  • Breakpad minidump 处理器:是一个程序(即:minidump_stackwalk),用于读取 minidump 文件和符号文件,并生成一个可读的 C/C++ 堆栈跟踪。

编译安装

  1. 下载 Breakpad 源码;

  2. 由于 Breakpad 依赖于 LSS,所以还需要下载它(地址:https://github.com/adelshokhy112/linux-syscall-support);

  3. 将 LSS 中的 linux_syscall_support.h 文件放至breakpad/src/third_party/lss/ 目录下;

  4. 编译 Breakpad,步骤非常简单:


$ cd breakpad
$ ./configure && make
$ make
$ sudo make install

成功之后,会生成 libbreakpad_client.a 库文件,以及dump_syms、minidump_stackwalk 等程序。

将 Breakpad 集成到程序中

和其他第三方库的用法一样,要将 Breakpad 集成到程序中,先要链接生成的库 libbreakpad_client.a,并设置包含路径为breakpad/src/,接下来就可以 include 头文件了。

为了生成 mindump 文件,我们需要实例化一个ExceptionHandler 对象,并提供一个存储 mindump 的路径,以及一个回调函数来接收关于已写入的 mindump 的信息:


#include "client/linux/handler/exception_handler.h"
#include

static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context,
bool succeeded)
{
std::cout << "Dump path:" << descriptor.path() << std::endl;

return succeeded;
}

void crash()
{
int* a = nullptr;
*a = 1;
}

int main(int argc, char* argv[])
{
google_breakpad::MinidumpDescriptor descriptor("/tmp");
google_breakpad::ExceptionHandler eh(descriptor, nullptr, dumpCallback, nullptr, true, -1);
crash();

return 0;
}

编译运行这个程序,会在 /tmp/ 目录下生成一个 minidump 文件,并在退出之前打印该文件的路径。

注意:在使用 Breakpad 时,需要目标程序内包含调试信息,这样dump_syms 工具才能从中解析出调试符号。而在默认情况下,Release 模式编译的程序是并不包含调试信息,若想包含,需要在编译程序时添加 -g 选项。

生成可读的堆栈跟踪

带调试信息的目标程序有了,minidump 文件有了,dump_syms 和minidump_stackwalk 等工具也有了,现在要做的就是生成有用的堆栈跟踪信息了!

1. 生成符号文件

Breakpad 要求我们将目标程序中的调试符号转换为文本格式的符号文件,这一步需要通过 dump_syms 工具来完成。

假设,我们的程序名为 test,执行以下命令,便会生成一个名为 test.sym 的符号文件:


$ dump_syms ./test > test.sym

2. 将符号文件放在特定目录下

为了使用这些符号,需要将生成的符号文件放在特定的目录结构中:

查看符号文件,第一行包含了生成目录结构所需的信息:


$ head -n1 test.sym
MODULE Linux x86_64 95E20E34BE203CB093B675D606A7D7D20 test

创建以上目录结构,并将符号文件移动到该路径下:


$ mkdir -p ./symbols/test/95E20E34BE203CB093B675D606A7D7D20
$ mv test.sym ./symbols/test/95E20E34BE203CB093B675D606A7D7D20/

3. 生成堆栈跟踪信息

当一切准备就绪,minidump_stackwalk 工具就派上用场了。

只需将 mindump 文件和符号路径作为命令行参数传递给它,便能生成堆栈跟踪信息了。为了便于分析,可以将输出重定向至文件中:


$ minidump_stackwalk /tmp/48596758-1d7a-4318-15edb4af-a9186ad7.dmp ./symbols > error.log

定位 Crash 所在位置

打开 error.log,搜索关键字“crashed”,一般与它最接近的一行,就是发生崩溃时程序的堆栈信息:

可以很清楚地看到,崩溃发生在 main.cpp 的第 16 行。

查看我们的测试程序,与预期结果一样:

至此,Crash 所在位置已经准确地定位到了,赶紧抓紧时间修改吧!

将上述过程脚本化

由于以上过程会经常执行,可以将其做成自动化脚本,不仅可有效防止步骤命令的遗忘,而且极大的加快了操作速度。

新建一个脚本 dumptool.sh,内容如下:


#!/bin/bash

if [ $# != 3 ] ; then
echo "USAGE: $0 TARGET_NAME DMP_NAME OUTPUT_NAME"
echo " e.g.: $0 test 48596758-1d7a-4318-15edb4af-a9186ad7.dmp error.log"
exit 1;
fi

#获取输入参数
target_file_name=$1
dmp_file_name=$2
output_file_name=$3

getSymbol() {
echo "@getSymbol: start get symbol"
dump\_syms ./$target_file_name > $target_file_name'.sym'
}

getStackTrace() {
echo "@getStackTrace: start get StackTrace"
sym_file_name=$target_file_name'.sym'

#获取符号文件中的第一行
line1=`head -n1 $sym_file_name`

#从第一行字符串中获取版本号
OIFS=$IFS; IFS=" "; set -- $line1; aa=$1;bb=$2;cc=$3;dd=$4; IFS=$OIFS

version_number=$dd

#创建特定的目录结构,并将符号文件移进去
mkdir -p ./symbols/$target_file_name/$version_number
mv $sym_file_name ./symbols/$target_file_name/$version_number

#将堆栈跟踪信息重定向到文件中
minidump_stackwalk $dmp_file_name ./symbols > $output_file_name
}

main() {
getSymbol
if [ $? == 0 ]
then
getStackTrace
fi
}

#运行main
main

使用比较简单,先为脚本增加可执行权限:


$ chmod +x ./dump_tool.sh

然后执行下述命令,将二进制文件、minidump 文件、输出日志文件作为参数传递给它:


$ ./dumptool.sh ./test /tmp/48596758-1d7a-4318-15edb4af-a9186ad7.dmp error.log

完成之后,所有的堆栈跟踪信息就会被输出到 error.log 文件中了。

很好用吧,学会这个绝招,让 C++ 崩溃无处可逃!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
恶心!演都不演了! 直接照搬7年前剧情!他毁了NBA

恶心!演都不演了! 直接照搬7年前剧情!他毁了NBA

阿浪的篮球故事
2024-06-15 20:43:42
王思聪21岁现任宣战!曝大量私照长腿吸睛颜值高,甜蜜躺女方腿上

王思聪21岁现任宣战!曝大量私照长腿吸睛颜值高,甜蜜躺女方腿上

裕丰娱间说
2024-06-15 18:49:24
新情况!上海造完山,又开始造雪:已达70厘米厚,今年启用;无人驾驶出租车也来了,连接浦东机场

新情况!上海造完山,又开始造雪:已达70厘米厚,今年启用;无人驾驶出租车也来了,连接浦东机场

上观新闻
2024-06-15 22:43:12
无缘美加墨世界杯?巴西男足遇黑暗时刻,网友:66年的辉煌终结

无缘美加墨世界杯?巴西男足遇黑暗时刻,网友:66年的辉煌终结

体坛知识分子
2024-06-15 06:05:02
凯特王妃与威廉王子首度公开亮相,暴瘦憔悴许多,三个孩子也出席

凯特王妃与威廉王子首度公开亮相,暴瘦憔悴许多,三个孩子也出席

笑猫说说
2024-06-15 17:47:08
天生“坏种”!被判10年的李天一出狱后,令人作呕的一幕出现了

天生“坏种”!被判10年的李天一出狱后,令人作呕的一幕出现了

琪琪故事记
2024-06-14 09:42:01
玫瑰的故事:刘亦菲的瘪臀、粗腰、粗腿,是对内娱畸形审美的反击

玫瑰的故事:刘亦菲的瘪臀、粗腰、粗腿,是对内娱畸形审美的反击

喵喵娱乐团
2024-06-14 17:56:07
难怪有人对父母感到心寒!看了网友的分享,心酸得想大哭一场

难怪有人对父母感到心寒!看了网友的分享,心酸得想大哭一场

镜头时光
2024-06-11 00:54:32
6月15日俄乌最新:对等空袭

6月15日俄乌最新:对等空袭

西楼饮月
2024-06-15 16:47:22
“母亲借钱买的”电瓶车不合标准被没收,女孩哭得撕心裂肺!

“母亲借钱买的”电瓶车不合标准被没收,女孩哭得撕心裂肺!

走读新生
2024-06-15 07:25:14
惊!河南3000万买五万吨水,高尔夫球场竟然耗水4000万吨?

惊!河南3000万买五万吨水,高尔夫球场竟然耗水4000万吨?

小毅讲历史
2024-06-15 05:31:15
越闹越大!官方紧急通告,涉事人员全部停职,司机被喷辣椒水不冤

越闹越大!官方紧急通告,涉事人员全部停职,司机被喷辣椒水不冤

乐阳聊军事
2024-06-15 18:34:44
最新积分榜!中国女排3-2爆冷掀翻世界第一,日本女排双重打击

最新积分榜!中国女排3-2爆冷掀翻世界第一,日本女排双重打击

开心体育站
2024-06-16 01:00:08
17岁中专生姜萍出圈,没人注意第345名的何金银,传闻是个外卖员

17岁中专生姜萍出圈,没人注意第345名的何金银,传闻是个外卖员

娱记掌门
2024-06-16 00:15:17
周鸿祎辟谣:小鸟壁纸不是360产品

周鸿祎辟谣:小鸟壁纸不是360产品

快科技
2024-06-15 18:18:15
不是周琦,不是张镇麟,中国男篮最新队长曝光,辽宁队球迷破防了

不是周琦,不是张镇麟,中国男篮最新队长曝光,辽宁队球迷破防了

宗介说体育
2024-06-15 14:03:02
世联赛最新排名出炉,中国女排第六,三球队争最后一个总决赛席位

世联赛最新排名出炉,中国女排第六,三球队争最后一个总决赛席位

湘楚风云
2024-06-16 02:19:01
这不红牌?罗德里破坏空门机会吃到黄点,佩里西奇疯狂抗议

这不红牌?罗德里破坏空门机会吃到黄点,佩里西奇疯狂抗议

直播吧
2024-06-16 01:48:20
​美国失算,嫦娥六号后,嫦七合作:禁阿反而来了7国,含盟友

​美国失算,嫦娥六号后,嫦七合作:禁阿反而来了7国,含盟友

环球科学猫
2024-06-15 11:17:14
罗斯人开始抛弃卢布,乌克兰愈战愈勇

罗斯人开始抛弃卢布,乌克兰愈战愈勇

非虚构故事
2024-06-13 13:28:47
2024-06-16 11:14:44
CSDN
CSDN
成就一亿技术人
24726文章数 241820关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

40余套房屋涉嫌"一房多卖" 有购房者内心积郁因病去世

头条要闻

40余套房屋涉嫌"一房多卖" 有购房者内心积郁因病去世

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

江宏杰秀儿女刺青,不怕刺激福原爱?

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

东风奕派eπ008售21.66万元 冰箱彩电都配齐

态度原创

艺术
手机
亲子
本地
公开课

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

手机要闻

这次稳妥了,小米15系列手机发布时间、配置信息都有了准信

亲子要闻

家庭教育争议:青春期孩子该如何管教?

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版