背景
在排查崩溃bug时自己很崩溃,想着如果有工具可以定位就好。上网搜了搜发现确实有,这样的工具,分别是Google公司的Breakpad和Crashpad,目前暂时使用Breakpad,因为Crashpad的一些资源需要去外网上面才能获取(主要是Google官网的编译说明以及相应的开发工具,如果有大佬知道怎么获取,请帮帮我)。
参考博客
这是一篇经验总结的文章,当然大部分都是借鉴他人的,所以附上参考的原文链接,感谢这些博主。我的总结也是再此基础上写的。
https://blog.csdn.net/libaineu2004/article/details/108033316
标题 : dump系列(3)Qt使用Google Breakpad或Crashpad捕获程序崩溃报告
https://blog.csdn.net/GoForwardToStep/article/details/56304285
标题 : Google Breakpad 在 windows下捕获程序崩溃报告
https://blog.csdn.net/zyhse/article/details/112577340
标题 : 在Windows下编译Breakpad
选择Breakpad与Crashpad的纠结
看了好多资料,发现说Breakpad已经被淘汰,Crashpad是正在使用的。不过我想Breakpad也够我用了,我可能用到的功能也不会太多。另外我看了看这个项目还有大牛们在维护。
过程(这一小节提到博客的连接在上面写了)
我首先参考的博客是Google Breakpad 在 windows下捕获程序崩溃报告(https://blog.csdn.net/GoForwardToStep/article/details/56304285)这篇,这里面提供了Breakpad项目的源码,如下图。
这里我选择去github上直接下载源码。用一个最新的。
https://github.com/google/breakpad
注意使用了github上的源码,那么Google Breakpad 在 windows下捕获程序崩溃报告文章的后面,有一些方法就不适用了。下面就会提到。
记得搭建python环境,我安装的版本也是2.7.13,使用上没有问题。
接着是安装GYP工具,博客中是这么写的,而我下载的源码中没有这个目录,这里就博客里面的不一样了。
GYP(Generate Your Projects)是由 Chromium 团队开发的跨平台自动化项目构建工具,Chromium 便是通过 GYP 进行项目构建管理。
而GYP在 源码的 \google_breakpad\src\tools \gyp 目录下。打开cmd命令提示窗口,进入到 \google_breakpad\src\tools \gyp 目录,输入命令 setup.py install ,完成gyp的安装。
接下来就可以参考博客在Windows下编译Breakpad( https://blog.csdn.net/zyhse/article/details/112577340),这里面提到了还需要额外的安装GYP工具,大家照着大佬说着做就可以了,但是在安装的时候(执行 setup.py install)我遇到了如下问题,我看大概意思是以管理员身份操作出的错。所以我就又添加了一个windows的普通用户,切换到普通用户再进行安装就好了,然后就编译源码,生成breakpad的库。
最后注意,使用库时还需要配合对应的头文件,下图是我包含的头文件,大家仅作参考,真正使用时要注意目录层级结构。
2022-08-17 补充
在执行完setup.py install 后,执行gyp -h 时我这边出现了ImportError: No module named six.moves,这个好像是模块版本的问题,执行pip install six,然后再来一遍上述操作就好了。
2022-08-18 补充 qt中使用
#include "mainwindow.h"
#include <QDir>
#include <QDebug>
#include <QApplication>
#include <QDateTime>
#include "exception_handler.h"
using namespace google_breakpad;
//breakpad需要的回调函数
bool callback(const wchar_t *dump_path,
const wchar_t *id,
void *context,
EXCEPTION_POINTERS *exinfo,
MDRawAssertionInfo *assertion,
bool succeeded)
{
if (succeeded)
{//注意!! 进到if中说明程序崩溃已经发生,此时这里不应该再进行耗时或者堆栈操作的行为
//最后存储dump文件的路径 xx/dump_path/xxxx-xx-xx-xx-xx-xx-xxx
//毫秒级别存储dump文件
QString path = QString::fromWCharArray(dump_path) + "/" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
QDir qdir(path);
if(!qdir.exists())
{
qdir.mkdir(path);
}
//旧的dump文件的路径 路径+文件
QString qoldfile = QString::fromWCharArray(dump_path) + "/" + QString::fromWCharArray(id) + ".dmp";
//新的dump文件的路径 路径+文件
QString qnewfile = path+"/"+QString::fromWCharArray(id) + ".dmp";
//剪切dump文件到新的目录
QFile qfile(qoldfile);
if(qfile.exists())
{
if(qfile.rename(qoldfile,qnewfile))
{
qDebug() << "cut dump file success";
}
}
qDebug() << "Create dump file success";
}
else
{
qDebug() << "Create dump file failed";
}
return succeeded;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建捕捉程序异常对象
QString qstrpath = "C://Dumps"; //创建目录Dumps ,用于存储所有dump文件
QDir qdir(qstrpath);
if(!qdir.exists())
{
qdir.mkdir(qstrpath);
}
ExceptionHandler eh(qstrpath.toStdWString(),
NULL,
callback,
NULL,
ExceptionHandler::HANDLER_ALL);
MainWindow w;
w.show();
return a.exec();
}
以上就是我在参考其他博客遇到问题时解决方法的总结,如果读者发现了错误,请及时指正,不胜感激。