mac下利用Breakpad的dump文件进行调试
一、前情回顾
最近把公司的一个视频处理程序更新了一个版本,准备提交测试的发现了崩溃的情况。这个程序采用Qt和ffmpeg技术栈开发,主要用于对视频进行渲染拼接处理,在Windows和mac两个平台同时进行发布。在windows上测试完一切正常,然而就在我以为一切大功告成的时候,测试的同事直接给我来了个当头棒喝,程序崩溃了!没有道理啊,同一套代码在Windows上安然无恙,在Mac上为何直接崩溃?好消息是程序在崩溃的时候保存了dump文件。

这得感谢前段时间集成的Google Breakpad了。Google Breakpad是Google开发的一个跨平台异常捕获和dump文件(准确的说是mini dump)生成的开发库。利用这个库可以在Windows, Mac, Linux, iOS, Android平台上对程序异常崩溃进行捕获,并生成dump文件供后期调试。据说Google Chrome, Chromium, Firefox都使用了这套机制,因此其可用性是经得起考验的,并且这个库现在依然更新的很频繁。

如此强大的东西,怎么使用呢?好在网上关于breakpad的资料是还是挺多的,只不过都不是很完整很简洁。要么就只介绍了实现原理、或者只介绍了怎么编译、或者就只介绍了怎么集成,对于新手使用非常不友善。这里就根据我在Windows和Mac两个平台的使用经验来总结下吧。
二、breakpad的使用
breakpad以源代码的形式发布,所以首先要从仓库中把代码下下来:
git clone https://chromium.googlesource.com/breakpad/breakpad
这个是Google的代码仓库,基于国内的环境需要把VPN打开。下载下来的代码包含了windows, mac, linux三个平台所有的文件了,也包含了各个平台的工具源码。没错,breakpad的工具需要自己编译。
假设源代码下载到了E:/breakpad,那么进入到这个目录运行make命令:
./configure
make
在Windows上需要用gyp工具来编译,所以还得下载gyp非常麻烦。在mac上就非常简单了,直接运行上述命令即可生成静态库文件。但是工具的话需要进入到tools目录,里面有个已经配置好的xcode工程,直接打开即可编译。

不过要注意的是,最新的breakpad源码在编译工具的时候会报错:
Undefined symbols for architecture x86_64:
"google_breakpad::BaseName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
google_breakpad::DumpSymbols::CreateEmptyModule(google_breakpad::scoped_ptr<google_breakpad::Module>&) in dump_syms.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
解决办法是:

在这一步中我们编译源码主要是为了得到两个工具:minidump_stackwalk和dump_syms。这两个分别有什么用呢?dump_syms用于从可执行程序中抽取出调试符号保存到syms符号文件中,而minidump_stackwalk则根据syms文件来分析mini dump文件,得到一个可读性强的崩溃调用堆栈。由于我的工程是基于Qt的,所以我直接利用了Github上面的一个开源项目进行编译。这个项目针对Qt剔除了一些无用的头文件,并对源代码做了稍微的调整。

基于QMake的工程,可以直接用Qt Creator打开编译。在Windows上和Mac上无缝支持。编译即可得到我们需要的lib文件了。这个在我们后面集成工程中链接需要用到。当然也可以直接将源代码集成到工程去。
接下来就讲讲如何集成吧。集成步骤其实非常简单,直接上代码:
#ifdef _WINDOWS
#include <client/windows/handler/exception_handler.h>
#else
#include <client/mac/handler/exception_handler.h>
#endif #ifdef _WINDOWS
bool minidumpCB(const wchar_t *dump_path, const wchar_t *id, void *context, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool succeeded) {
#else
bool minidumpCB(const char* dump_path, const char* id, void* context, bool succeeded) {
#endif
if (succeeded) {
std::wcout << "Mini Dump file: " << id << ".dump Path: " << dump_path << std::endl;
}
return succeeded;
} int main() {
#ifdef NDEBUG // 只在Release模式下启用Breakpad
#ifdef _WINDOWS
google_breakpad::ExceptionHandler eh(dumpLocation.toStdWString(), NULL, minidumpCB, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL);
#else
google_breakpad::ExceptionHandler eh(dumpLocation.toStdString(), NULL, minidumpCB, NULL, true, NULL);
#endif
#endif
}
接口非常简单,只要定义一个回调函数minidumpCB()。当程序崩溃被捕捉到的时候就会调用这个函数,这里只是输出了mini dump文件保存的位置。如果第一张截图中的红框所示。
三、dump文件如何利用
生成的dump文件如何利用?如何转换成我们能看得懂的调用堆栈信息?其实有上面编译出来的两个工具,接下来的工作分三个步骤:
- 使用dump_syms生成符号表:
./dump_syms ~/Test/Caputre > Capture.syms
- 创建有层次的调试符号文件夹:
head -n1 Capture.syms // 查看文件层次
mkdir -p ./symbols/PanoramaCapture/3EXXXXXX/ //这一步根据上面的输出来
mv Capture.syms ./symbols/PanoramaCapture/3EXXXXX/ // 将符号文件移动进去 - 利用minidump_stackwalk分析dump文件:
./minidump_stackwalk minidump.dmp ./symbols

最后一步将输出详细的堆栈信息:

相信有了这些信息,找出代码中潜伏的bug不是什么难事了。而我也正是根据这些信息,成功解决了这次的崩溃问题。再提一句,不管在Windows上还是Mac上,编译Release的时候最好把调试符号文件保存好。这样利用breakpad来分析的时候才能事半功倍,breakpad方才能展现其强大的一面。
四、参考链接
1.https://www.jianshu.com/p/295ebf42b05b
2. https://github.com/google/breakpad
3. https://groups.google.com/forum/#!topic/google-breakpad-discuss/fierVnIAv1M
4. https://github.com/gyunaev/google-breakpad-qt
mac下利用Breakpad的dump文件进行调试的更多相关文章
- Mac下利用SSH进行传输文件(转)
//1.从服务器上下载文件 scp username@servername:/path/filename /var/www/local_dir(本地目录) //例如scp root@192.168.0 ...
- Mac下利用(xcode)安装git
Mac下利用(xcode)安装git 一.AppStore 最安全途径:搜索下载Xcode,(需要AppleID). 其他:直接百度Xcode下载. 二.Xcode 打开Xcode-->Pref ...
- mac下为Apache 创建 .htaccess文件
标签:mac .htaccess 在设置固定链接时会提示如下的问题: 若您的 .htaccess 文件可写,我们可以自动修改它.但似乎它不可写,因此我们在下方列出了您 .htaccess 文件 ...
- 利用VS2005进行dump文件调试
前言:利用drwtsn32或NTSD进行程序崩溃处理,都可以生成可用于调试的dmp格式文件.使用VS2005打开生成的DMP文件,能很方便的找出BUG所在位置.本文将讨论以下内容: 1. 程序编译选 ...
- 利用VS2005进行dump文件调试(17篇博客)
前言:利用drwtsn32或NTSD进行程序崩溃处理,都可以生成可用于调试的dmp格式文件.使用VS2005打开生成的DMP文件,能很方便的找出BUG所在位置.本文将讨论以下内容: 1. 程序编译选 ...
- Windows下利用Windbg 分析dump
概述: 注册生成dump文件的函数. 当程序收到没有捕获的异常时,调用上述函数,生成dump文件. 利用Windbg结合编译程序时生成的pdb和代码来分析dump文件,定位问题. 如下代码生成dump ...
- VC++ 利用PDB和dump文件定位问题并进行调试
转载:https://blog.csdn.net/zfs_kuai/article/details/43646665 转载:https://blog.csdn.net/i_chaoren/articl ...
- linux 下如何打开core dump文件开关
dump文件可以在程序crash时,方便我们查看程序crash的地方和上下文信息.在window下,要能生成dump文件,需要自己编写相应的代码.不过现在网上可以找到相应的代码,只要把它下载后然后加到 ...
- mac 下 使用 java运行 class 文件 总是提示 “错误: 找不到或无法加载主类”的解决方法
发现问题 切换到mac平台后,突然想写点程序运行在mac下,想到mac自带java,会方便好多.不过在这过程中遇到了麻烦: 总是提示 “错误: 找不到或无法加载主类” 工程结构 查了好久,终于找到原型 ...
随机推荐
- centos7 mongodb 3.4 yum 安装
3.4 vi /etc/yum.repos.d/mongodb-3.4.repo [mongodb-org-3.4] name=MongoDB Repository baseurl=https:/ ...
- Docker系统六:Docker网络管理
Docker网络 I. Docer的通信方式 默认情况下,Docker使用网桥(brige)+ NAT的通信模型. Docker启动时会自动创建网桥Docker0,并配置ip 172.17.0.1/1 ...
- 和scikit-learn打个招呼
1.先装对应的库.不能偷懒,都得装,不然飞不起来. pip install scikit-learn pip install numpy pip install scipy 2.测试如下代码. imp ...
- Kettle参数化配置
Kettle参数化配置 在做系统化的Kettle实现方案,我们基本要定义一些不变的参数,在整个生命周期中使用,或者设置一些特定的参数,在一些特定的JOB中使用.参数化配置有利用我们Kettle实现规范 ...
- 从零开始学习前端JAVASCRIPT — 12、JavaScript面向对象编程
一.构造函数的使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Flex中通过RadioButton进行切换
1.页面切换 <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx=& ...
- javascript 学习笔记 三大特性
<script type="text/javascript"> //封装 function Person (name,age,sal){ this.name=name; ...
- 修改windows7中文件的权限
1.修改ntkrnlpa.exe的权限 2.鼠标右键,选择"属性" 3.单击"安全"选项,选择"高级" 4.在高级安全设置中,选择" ...
- zTree实现删除树节点
zTree实现删除树节点 1.实现源码 <!DOCTYPE html> <html> <head> <title>zTree实现基本树</titl ...
- 利用PowerDesigner15在win7系统下对MySQL 进行反向工程(一)
利用PowerDesigner15在win7系统下对MySQL 进行反向工程 1.首先,安装以下的驱动 2.找到"C:\Windows\System32" 3.双击"od ...