Google Breakpad是什么?

  一个开源的多平台崩溃报告系统。

  Google breakpad是一个非常实用的跨平台的崩溃转储和分析模块,它支持Windows,Linux和Mac和Solaris。由于他本身跨平台,所以很大程度上减少了我们在平台移植时的工作,毕竟崩溃转储,每个平台下都不同,使用起来很难统一,而Google breakpad就帮我们做到了这一点,不管是哪个平台下的崩溃,都能够进行统一的分析。

  现在很多工程都在使用它:最著名的几个如Chrome,Firefox,Picasa和Google Earth。另外他的License是BSD的,也就是说,我们即便是在商业软件中使用,也是合法的。好东西!

Google Breakpad原理(比较抽象)

breakpad把应用程序分成三个部分,代码,breakpad客户端和调试信息。

      1. 在build system中,通过symbol dumper用平台相关的调试信息生成平台无关的symbol文件。这样做的好处很明显,一旦平台无关了,所有平台的崩溃就可以做统一的分析了。

  2. breakpad采取进程外转储和分析崩溃的方式,他使用C/S结构,客户端用来捕获当前进程中发生的崩溃,并通知服务端崩溃发生。服务端用来响应客户端,抓取dump文件。这样做的目的是为了减少崩溃进程对dump的影响

  3. Dump生成后转发到崩溃分析器中,这个部分可以在本地也可以在服务器上,它对Dump文件进行解析,生成可读的堆栈信息。

Google Breakpad安装和编译(Windows)

  1、  下载Google breakpad源代码(从svn中签出最新代码)

  2、  安装python(2.7版本可用)

  3、  生成Windows工程文件

  cd  "源码目录/src/tools/gyp"
  # 注意,此处不能使用全路径,不然会出错
  gyp.bat --no-circular-check "../../client/windows/breakpad_client.gyp"

  

  4、  Build All

  备注:如果无法通过svn下载源代码,可在CSDN上利用网友分享的。

Google Breakpad的使用

在Windows下使用breakpad的方法很简单,只需要创建一个ExceptionHandler的类即可,这个ExceptionHandler就是用户捕获崩溃的类。

  handler = new ExceptionHandler(const wstring& dump_path,
FilterCallback filter,
MinidumpCallback callback,
void* callback_context,
int handler_types,
MINIDUMP_TYPE dump_type,
const wchar_t* pipe_name,
const CustomClientInfo* custom_info);

参数说明:

  l  //dump文件路径。

  l  //crash时调用回调函数,返回ture/false来继续/停止异常处理。

  l  //minidump写入后调用的回调函数

  l  //设备上下文,回调使用的

  l  //HandlerType异常类型,可在exception_handler.h查看

  l  //minidump的类型,使用DbgHelp.h中MINIDUMP_TYPE类型

  l  //接收crash的server端的管道名

  l  //使用OOP产生minidump时,使用这个自定义客户信息类指针来发送自定义数据

使用breakpad的时候,有两个地方需要注意:

  1. 把breakpad的solution下的几个工程,包含到你开发的工程中,或者直接包含它们的lib。

    common:基础功能,包含一个对GUID的封装和http上传的类。

    exception_handler:用来捕获崩溃的类。

    crash_generation_server:breakpad的服务端,用来在产生崩溃时抓取dump。

    crash_generation_client:breakpad的客户端,用来捕获当前进程的崩溃。

  2. 在初始化breakpad之前,记得先创建好dump文件的目录,不然breakpad服务端将不能正常的写dump,这会导致breakpad客户端在崩溃时无限等待服务端dump写完的消息,最后失去响应。

进程内抓取Dump

  进程内抓取Dump文件是最简单的breakpad的用法。 

 bool InitBreakpad()
{
google_breakpad::ExceptionHandler *pCrashHandler =
new google_breakpad::ExceptionHandler(L"c:\dumps",
onExceptionFilter,
onMinidumpDumped,
NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL,
MiniDumpNormal,
NULL,
NULL); if(pCrashHandler == NULL)
{
return false;
} return true;
}

进程外抓取Dump

  使用进程外抓取Dump是比较推荐的做法。使用进程外抓取Dump时,需要指定服务端和客户端,在服务端中需要创建CrashGenerationServer的实例,而在客户端中则只需要创建ExceptionHandler即可。此外,如果服务端自己需要抓进程内的Dump,请将pipe的参数置为NULL。

 const wchar_t s_pPipeName[] = L"\\.\pipe\breakpad\crash_handler_server";
const std::wstring s_strCrashDir = L"c:\dumps"; bool InitBreakpad()
{
google_breakpad::CrashGenerationServer *pCrashServer =
new google_breakpad::CrashGenerationServer(s_pPipeName,
NULL,
onClientConnected,
NULL,
onClientDumpRequest,
NULL,
onClientExited,
NULL,
true,
&s_strCrashDir); if(pCrashServer == NULL)
{
return false;
} if(!pCrashServer->Start())
{
delete pCrashServer;
pCrashServer = NULL;
} google_breakpad::ExceptionHandler *pCrashHandler =
new google_breakpad::ExceptionHandler(s_strCrashDir,
onExceptionFilter,
onMinidumpDumped,
NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL,
MiniDumpNormal,
(pCrashServer == NULL) ? s_pPipeName : NULL,
NULL); if(pCrashHandler == NULL)
{
return false;
} return true;
}

Google Breakpad代码分析

       代码结构

  在我们来看breakpad是如何实现其强大的功能之前,我们先来看一下他的代码结构吧。

Google breakpad的源代码都在src的目录下,分为如下几个文件夹:

  client:这下面包含了前台应用程序中捕捉dump的部分代码,里面按照平台分成各个子文件夹

  common:前台后台都会用到的部分基础代码,字符串转换,内存读写,md5神马的

  google_breakpad:breakpad中公共的头文件

  processor:用于在后台处理崩溃的核心代码

  testing:测试工程

  third_party:第三方库

  tools:一些小工具,用于处理dump文件和符号表

Google Breakpad的崩溃捕获机制

  在Windows下捕获崩溃,大家很容易会想到那个捕获结构化异常的Api:SetUnhandledExceptionFilter。

  breakpad中也使用了这个Api来实现的崩溃捕获,另外,breakpad还捕获了另外两种C++运行库提供的崩溃,一种是使用_set_purecall_handler捕获纯虚函数调用产生的崩溃,还有一种是使用_set_invalid_parameter_handler捕获错误的参数调用产生的崩溃。

breakpad中的C/S结构

  由于breakpad是在进程外抓取dump,所以breakpad需要实现一个C/S结构来处理崩溃进程抓取dump的请求。

  breakpad中使用了命名管道来实现IPC。

  (1)、Register

  客户进程连接上服务进程:连接上管道,设置管道状态

  客户进程向服务进程注册:通过NamedPipe,将客户进程的信息传递给服务进程,也从服务进程读取到数据。

  客户进程传递的数据包括:服务进程ID、dump类型、crash线程id的地址、EXCEPTION_POINTERS指针的地址、参数异常和纯虚函数异常的断言信息地址、客户进程信息。服务进程会监控客户进程的退出。

  客户进程接收的数据包括:客户进程用于触发生成dump的Event Handle;客户进程用于监听的dump生成完毕Event Handle;客户进程用于监听的服务进程活着Mutex handle等。

  客户进程在TransactNamePipe函数执行完毕之后,再执行了一次WriteFile操作,发送MESSAGE_TAG_REGISTRATION_ACK消息给服务进程,服务进程收到该ACK消息时,关闭跟客户进程的连接。服务进程对管道的操作顺序为:读-->写-->读,第二次读是客户进程通知服务进程关闭管道。

  在客户端,初始化ExceptionHandler的时候,如果指定了PipeName,也就表示此时需要使用进程外的dump抓取,ExceptionHandler会建立一个 CrashGenerationClient的对象,由这个对象连接服务端,将自己注册到服务端上去。注册的过程会顺序调用IsRegistered、ConnectToServer、ConnectToPipe、RegisterClient等函数。

  大家可以参看exception_handler.cc中的ExceptionHandler::Initialize函数。

  在服务端,初始化CrashGenerationServer的时候,就会建立一个命名管道,并等待客户端来连接(OnPipeConnected)。一旦有客户端连接上来(HandleReadDoneState),服务端会为每一个客户端生成一个ClientInfo的对象,之后用这个对象来管理所有的客户端(ClientInfo::Initialize()),并创建客户连接句柄将连接结果信息(PrepareReply、DuplicateHandle)回送给客户端(RespondToClient),客户端接收到回送信息(ValidateResponse)。

(2)、RequestDump

  一旦有崩溃发生,客户端就会向服务端请求Dump(RequestDump),服务端响应(OnDumpRequest)就会从这个ClientInfo对象中取出dump所需要的信息,具体地,通过RegisterWaitForSingleObject注册了崩溃Event Handle的回调函数。回调函数里做了这么几件事情:

  1)、通过ReadProcessMemory读取客户进程的信息;

  2)、生成dump;  

  3)、触发dump生成事件,通知客户进程,复位触发dump事件。

  大家可以参看crash_generation_server.cc中的CrashGenerationServer::HandleReadDoneState函数。

Google Breakpad存在的问题

  进程外生成dump有很多好处,其中最大的好处就是不会被崩溃进程影响,这样dump的过程就不容易出错,但是这样也有一定的弊端。

  1. 部分崩溃无法抓取。在一些极端的崩溃,如堆栈溢出之类的崩溃,进程外抓取dump有时候会失败。

  2. 无法抓取死锁或者其他原因导致的进程僵死。breakpad现在没有检测进程死锁的代码,也没有在服务端控制客户端请求dump的代码,所以现在breakpad无法抓取死锁等进程僵死的问题。

  3. 对服务端有依赖。如果指定了在使用进程外抓取dump,breakpad对服务端就有依赖。主要体现在抓取dump时,如果服务端不存在,客户端将无法正常抓取dump,甚至有时会出现阻塞。

PS:深入理解实现方式请调试Breakpad源代码。

C++库(Google Breakpad)的更多相关文章

  1. Google Breakpad 完全解析(二) —— Windows前台实现篇

    原创文章,转载请标明出处:Soul Apogee (http://bigasp.com),谢谢. 好,看完了如何使用breakpad,我们现在看看breakpad在Windows下到底是如何实现的呢? ...

  2. Google Breakpad: 实战crash .

    Google Breakpad: 实战crash . http://blog.csdn.net/zm_21/article/details/24795205 C/C++程序最棘手的时候就是一个字“挂” ...

  3. x86 Android游戏开发专题篇之使用google breakpad捕捉c++崩溃(以cocos2dx为例)

    近期一直都在x86设备上进行游戏开发.就c++层和Android java层倒没有什么要特别注意的(除了须要注意一下改动Application.mk指定平台外),在c++崩溃的时候,非常多时候看不到堆 ...

  4. google breakpad 使用初步总结

    项目地址:https://code.google.com/p/google-breakpad/    访问不了请挂VPN 这是一个由google主导的开源项目,官方介绍为:An open-source ...

  5. an introduction of google breakPad for android

    一.背景 众所周知,Android JNI层的Crash问题是个比较头疼的问题.相对Java层来说,由于c/c++造成的crash没有输出如同 Java的Exception Strace,所以cras ...

  6. Android使用google breakpad捕获分析native cash

    Android 开发高手课 课后练习(1) 一.Chapter01 崩溃 https://time.geekbang.org/column/article/70602 https://github.c ...

  7. QT中使用google breakpad捕获程序崩溃异常

    今天给大家介绍一个在linux下如何捕获程序崩溃异常的方法 一.google breakpad源码的下载和编译 1.https://github.com/google/breakpad.git,源码地 ...

  8. Google BreakPad使用集

    Google Breakpad 学习笔记 - 简书   Qt中使用Google Breakpad捕获程序崩溃异常_Linux编程_Linux公社-Linux系统门户网站 

  9. Google Breakpad 完全解析(一) —— Windows入门篇

    原创文章,转载请标明出处:Soul Apogee (http://bigasp.com),谢谢. Google breakpad是一个非常实用的跨平台的崩溃转储和分析模块,他支持Windows,Lin ...

随机推荐

  1. 命名空间“System.Web”中不存在类型或命名空间名称“HttpUtility”。是否缺少程序集引用?

    vs2010下解决方案: 1.右击项目选择“属性”,目标框架选择“.net FrameWord 4”; 2.右击项目中的引用,添加引用,在.net下选择System.Web,确定OK. 解释: fra ...

  2. js版弹力球实例

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>弹 ...

  3. 计算机中位(bit), 字节(byte), 字(word)的关系

    1.位(bit) 来自英文bit,音译为“比特”,表示二进制位.位是计算机内部数据储存的最小单位,11010100是一个8位二进制数.一个二进制位只可以表示0和1两种状态(21):两个二进制位可以表示 ...

  4. shiro登陆后没有返回设置的successUrl?

    第一次学习shiro的时候,并没有发现很大的问题.但后来在做项目的时候,特别是当访问的url是iframe的页面的时候,session又过期了,跳转到登陆页,完成登陆操作后,返回了只有iframe的页 ...

  5. 正则表达式解析url参数

    解析url参数正则:(?<=\?|&)[\w\={}\\\\,-:'\s'""]*(?=[^#\s]|) 意思是(?<=\?|&) 从?或&符号 ...

  6. 洛谷P2434 [SDOI2005]区间

    题目描述 现给定n个闭区间[ai, bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排列 ...

  7. java集合学生管理系统

    //student.java package com.sran.www; import java.util.Arrays; import java.util.Scanner; public class ...

  8. TypeScript Writing .d.ts files(编写声明文件)

    当使用扩展的JavaScript库或者插件API的时候,将需要使用声明文件(.d.ts)来描述库的类型.本文内容将包括如何编写声明文件相关的一些高级概念,然后用一些例子来展示如何将各式各样的概念与声明 ...

  9. 【Beta】第四次任务发布

    PM 日常管理&dev版宣传(周日开始). 后端 #99 服务发布 验收条件:使dev版能在www.buaaphylab.com下运行. 前端 #87 登录后能够查看与下载用户收藏的报告.生成 ...

  10. NOIp2016 十连测 round1

    Claris大爷出的一套模拟题.问别人要到了一份题,加深了自己NOIp要滚粗的感觉. Matser zzDP题,我只能说我第一遍写的时候还写崩了QAQ. //master //by Cydiater ...