C++库(Google Breakpad)

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就是用户捕获崩溃的类。

 1  handler = new ExceptionHandler(const wstring& dump_path,
 2                                FilterCallback filter,
 3                                MinidumpCallback callback,
 4                                void* callback_context,
 5                                int handler_types,
 6                                MINIDUMP_TYPE dump_type,
 7                                const wchar_t* pipe_name,
 8                                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的用法。 

 1 bool InitBreakpad()
 2 {
 3     google_breakpad::ExceptionHandler *pCrashHandler =
 4         new google_breakpad::ExceptionHandler(L"c:\dumps",
 5         onExceptionFilter,
 6         onMinidumpDumped,
 7         NULL,
 8         google_breakpad::ExceptionHandler::HANDLER_ALL,
 9         MiniDumpNormal,
10         NULL,
11         NULL);
12 
13     if(pCrashHandler == NULL)
14     {
15         return false;
16     }
17 
18     return true;
19 }

进程外抓取Dump

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

 1 const wchar_t s_pPipeName[] = L"\\.\pipe\breakpad\crash_handler_server";
 2 const std::wstring s_strCrashDir = L"c:\dumps";
 3 
 4 bool InitBreakpad()
 5 {
 6     google_breakpad::CrashGenerationServer *pCrashServer = 
 7         new google_breakpad::CrashGenerationServer(s_pPipeName,
 8                 NULL,
 9                 onClientConnected,
10                 NULL,
11                 onClientDumpRequest,
12                 NULL,
13                 onClientExited,
14                 NULL,
15                 true,
16                 &s_strCrashDir);
17 
18     if(pCrashServer == NULL) 
19     {
20          return false;
21     }
22 
23     if(!pCrashServer->Start()) 
24     {
25         delete pCrashServer;
26         pCrashServer = NULL;
27     }
28 
29     google_breakpad::ExceptionHandler *pCrashHandler = 
30         new google_breakpad::ExceptionHandler(s_strCrashDir,
31                   onExceptionFilter,
32                   onMinidumpDumped,
33                   NULL,
34                   google_breakpad::ExceptionHandler::HANDLER_ALL,
35                   MiniDumpNormal,
36                   (pCrashServer == NULL) ? s_pPipeName : NULL,
37                   NULL);
38 
39     if(pCrashHandler == NULL) 
40     {
41         return false;
42     }
43
44    return true;
45}

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源代码。

转载于:https://www.cnblogs.com/MakeView660/p/6077436.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java eleven进度条

2019独角兽企业重金招聘Python工程师标准>>> 一个矩形组件 MethodDescribleJProgrssBar()不带进度字符,最小值0最大值100的水平进度条JProgressBar(int orient)VERTICAL/HORIZONTALJProgressBar(int in,int max)指定最大最小的水平进度条JProgressBar(in…

Docker:多阶段构建 ASP.NET Core 应用镜像

本文选自『.NET大牛之路』知识星球,发布于2022年05月25日。今天我们一起来写 Dockerfile 构建一个 ASP.NET Core 应用镜像,同时还会将镜像发布到 Docker Hub 仓库。1创建示例 Web 应用程序为了演示,我们先创建一个 ASP.NET Core 应用程序&…

[转]【JAVA各版本特性】JAVA 1.0

闲来想了解下各版本之间的特性,搜索没有最新的特性说明,故想写一份。废话不多说。 JDK Version 1.0 1996-01-23 Oak(橡树) 初代版本,伟大的一个里程碑,但是是纯解释运行,使用外挂JIT,性能比较差&#xff0…

北京Uber优步司机奖励政策(3月11日)

滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfryf/p/4612609.html 优步奖励低/不挣钱/怎么办?看这里:http://www.cnblogs.com/mfry…

【招聘(广州)】成功易(广州).Net Core中高级开发工程师

成功易(广州)信息技术有限公司简介成功易是一家集团性公司,创立于2002年,总部位于北京,旗下拥有7家子公司。广州成功易成立于2019年,人员逐渐增长150人,组织架构完善, 我们是腾讯广告…

xcode 设置快捷键 整行上下移动

2019独角兽企业重金招聘Python工程师标准>>> 设置整行代码上下移动:找到Xcode中的自带的配置文件:/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist用文本编辑IDETextKeyBind…

用.Net Core接入微信公众号开发

Part1前言最近想写一点基于.Net Core微信公众号开发的文章Part2测试公众号申请测试公众号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login微信公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html通过微…

腾讯、百度、小米等7家互联网各大厂的中台建设怎么样了?

中台是真正为前台而生的平台(可以是技术平台,业务能力甚至是组织机构),它存在的唯一目的就是更好的服务前台规模化创新,进而更好的响应服务引领用户,使企业真正做到自身能力与用户需求的持续对接。 以下转载…

JAVA基础知识之网络编程——-基于AIO的异步Socket通信

异步IO 下面摘子李刚的《疯狂JAVA讲义》 按照POSIX标准来划分IO,分为同步IO和异步IO。对于IO操作分为两步,1)程序发出IO请求。 2)完成实际的IO操作。 阻塞IO和非阻塞IO都是针对第一步来划分的,如果发出IO请求会阻塞线程…

基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

EditPlus 文件查找功能:在指定文件夹,用正则查寻包含指定内容的文件,指定文件类型,并排除特殊文件名文件

单击菜单栏上的【Search】&#xff08;查找&#xff09;&#xff0c;选择【Find in Files】&#xff08;在文件中查找&#xff09;命令&#xff1a; 查找项&#xff1a;正则查找video标签&#xff0c;src为不包含http的mp4 <video src"([^http].*\.mp4)" width&q…

NOIP2016普及组第三题——海港

题目描述 小K是一个海港的海关工作人员&#xff0c;每天都有许多船只到达海港&#xff0c;船上通常有很多来自不同国家的乘客。 小K对这些到达海港的船只非常感兴趣&#xff0c;他按照时间记录下了到达海港的每一艘船只情况&#xff1b;对于第i艘到达的船&#xff0c;他记录了这…

7z-linux下解决中文名乱码的终极办法

为什么80%的码农都做不了架构师&#xff1f;>>> linux上安装7z主要是为了解决中文文件名乱码的问题&#xff0c;压缩率还是其次原因 具体安装看参考网址&#xff0c;建议用源码方式安装 官网下载地址&#xff1a;http://www.7-zip.org/download.html 源文件项目地址…

工具箱之 IKVM.NET 项目新进展

在各种群里经常讨论的一个事情是.NET 如何调用 Java 的实现&#xff0c;最常见的场景之一就是在加解密方面Java提供的密钥&#xff0c;C#无法解密&#xff0c; C#中byte范围是[0,255]&#xff0c;而Java中的byte范围是[-128,127]&#xff0c;由于密码生成器是java所独有的&…

一天一种设计模式之六-----工厂方法模式

2019独角兽企业重金招聘Python工程师标准>>> 一.工厂方法模式 工厂方法模式属于创建型模式。工厂方法模式定义&#xff1a;定义一个用于创建对象的借口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到了他的子类。一般工厂类会有一个工厂的接…

[转]IPython介绍

1. IPython介绍 ipython是一个python的交互式shell&#xff0c;比默认的python shell好用得多&#xff0c;支持变量自动补全&#xff0c;自动缩进&#xff0c;支持bash shell命令&#xff0c;内置了许多很有用的功能和函数。学习ipython将会让我们以一种更高的效率来使用python…

.NET MAUI in Mac

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;4分钟&#xff09;概要本篇文章主要分享MAUI在m1芯片的设备上运行和支持情况&#xff0c;将我们写好的MAUI程序编译为支持mac平台的版本。在m1芯片刚刚出来的时候有很多开发工具和应用程序对m1芯片的支持不是很友好&a…

前端开发中的SEO

前端开发中的SEO 什么是SEO SEO由英文Search Engine Optimization缩写而来&#xff0c;中文意译为“搜索引擎优化”。SEO是指从自然搜索结果获得网站流量的技术和过程&#xff0c;是在了解搜索引擎自然排名机制的基础上&#xff0c;对网站进行内部及外部的调整优化&#xff0c;…

C# 自定义并动态切换光标

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;唐宋元明清的博客原文地址&#xff1a;https://www.cnblogs.com/kybs0/p/14873136.html系统有很多光标类型 &#xff1a;Cursors 类 (System.Windows.Input) | Microsoft Docs[1]本章介绍如…

视频播放器for android

写在前面 好久没有写博客了, 中间忙了一堆杂七杂八的事情...工作, 情感, 未来, 人生... 下面是正文 一直要写一个视频播放器, 好练练手. 这个app, 从年前写到现在, 终于算弄出了样子, 0.0版本. (不得不说, googleVPN值得拥有, android developer网站, android sdk samples, sta…