windows下捕获dump之Google breakpad_client的理解
breakpad是Google开源的一套跨平台工具,用于dump的处理。很全的一套东西,我这里只简单涉及breakpad客户端,不涉及纯文本符号生成,不涉及dump解析。
一、使用
最简单的是使用进程内dump捕获,使用者只需要跟ExceptionHandler打交道,在自己的程序里定义一个ExceptionHandler对象,ExceptionHandler会挂上异常处理、CRT参数错误处理、purecall错误处理,当发生crash时,breakpad会写好dump,然后回调通知使用者。进程内dump并不推荐,但也不算太差,它在程序启动时就开启了一个“Handler thread”,等到有crash,触发该线程去写dump,写完回调使用者,从google的久未更新的ClientDesign文档可以猜到以前是只有进程内写dump的,它已经符合了让dump尽可能真实而设置下的规定。以前所在团队在chromium上做二次开发,使用的是进程内dump,没发现有问题。现在我安装的chrome浏览器,没发现有crash_server进程,估计要么是没抓dump,要么是进程内dump,我看到有文章说有一个GoogleCrashHandler.exe进程,但我这里没有发现,可能是后来修改掉了吧,之前我还一直以为是对crash_server.exe重命名了。
进程外写dump,使用者一样要定义一个ExceptionHandler对象,这对象有管道名称。另外还需要写一个server进程,server进程负责:写dump、上传dump,当客户进程发生crash时,只需要通过Event置位通知服务进程。server进程只需要定义一个breakpad提供的CrashGenerationServer类对象。客户进程和服务进程是通过管道通信的,通信可以只发生在客户进程初始化阶段,server进程要先于客户进程启动,否则客户进程就会因为管道连接不上而使用进程内dump捕获。
进程内、外dump捕获,都是异步而阻塞的,异步具体是说,进程内dump会让写dump、回调通知使用者写dump完成在另一个安全的线程中做;进程外dump会让写dump在另一个进程中做、回调通知写dump完成在crash线程中做、dump上传可以放到另一个进程中做。阻塞具体是说,虽然发生crash的线程把dump相关的工作扔给别人做了,但是它会等待别人的工作做完才继续完下走。
二、内部实现
ExceptionHandler部分。
当使用进程内dump时,会有一个handler thread,该线程启动之后,等待semaphore触发写dump行为,进程外dump则没有该线程。另外,异常处理初始化是在ExceptionHandler对象构造中做的,如果没有进程外dump的需求,那么只需要ExceptionHandler就可以搞定,不需要CrashGenerationClient 和 CrashGenerationServer。


可以看到breakpad客户端主要包含了CrashGenerationServer\ExceptionHandler\CrashGenerationClient三部分,另外有dump上传未画出。
三、从代码中学到的
学习breakpad_client的代码,不是为了在工作上使用,以前的、现在的团队都已经有成熟的dump捕获、dump分析工具。学习它,是为了体会它的优点和缺点。
breakpad_client的层次划分很好,使用者不需要知道进程间通信的存在,通过回调实现层次间的通知。(这种比较简单,一般人都可以做到。)
crash之后崩溃线程尽可能少的操作,在客户进程初始化时就把崩溃时服务进程需要用的全局数据的地址通知服务进程,崩溃时,只需要触发Event。(我之前的做法是在crash的时候再把崩溃信息通知服务进程,现在看来是不合理的。)
API的使用。RegisterWaitForSingleObject的使用,这个API是我之前没用过的,非常方便,直到前阵子才通过QueueUserWorkItem API(chromium通过它异步上传dump)知道windows有自带线程池的存在;进程间通信对管道+Event的善用(管道的异步操作 + RegisterWaitForSingleObject 非常漂亮);dump生成的各种处理,不仅仅是MiniDumpWriteDump。(这可以说是我知识面不广带来的惊喜。)
阅读ClientDesign文档,虽然文档可能老了,但引导我明白了为什么进程内dump会导致现场破坏,最直接的理解是:因为堆坏了导致的崩溃,这时候异常处理函数里又干了堆内存分配的事情,那肯定就又继续crash。
breakpad_client对使用者的通知是用回调函数做的,回调函数是在对象初始化时传递的函数指针,有一个函数有三个回调函数指针(客户进程连接、客户进程崩溃、客户进程要求上传dump), 我更喜欢用抽象类指针,这样子只需要一个指针就够了,参数不需要那么多,而且代码更像C++。(这是目前唯一能想到的不喜欢。)
四、资料推荐
http://code.google.com/p/google-breakpad/wiki
windows下捕获dump之Google breakpad_client的理解的更多相关文章
- windows下捕获dump之Google breakpad_client
breakpad是Google开源的一套跨平台工具,用于dump的处理.很全的一套东西,我这里只简单涉及breakpad客户端,不涉及纯文本符号生成,不涉及dump解析. 一.使用 最简单的是使用进程 ...
- windows下捕获dump之守护进程
一两个月前为产品写了一个独立的exe,由于产品使用的捕获dump是一个现成的进程外exe,如果以资源的方式集成它容易出现安全警告,由于时间关系没有寻求新的解决方法,还是遵循旧方案,不捕获dump. 最 ...
- windows下捕获dump
一般要捕获异常只需要两个函数:SetUnhandledExceptionFilter截获异常:MiniDumpWriteDump写dump文件.但是由于CRT函数可能会在内部调用SetUnh ...
- Google Breakpad 在 windows下捕获程序崩溃报告
http://blog.csdn.net/goforwardtostep/article/details/56304285
- Windows下获取Dump文件以及进程下各线程调用栈的方法总结(转)
1. Dump文件的用途 Dump文件, 主要用于诊断一个进程的运行状态,尤其是碰到崩溃(Crash)或者挂起(hang)不响应时,需要分析它的工作状态. 除了平时常见的attach到这个进程, 分 ...
- windows下捕获本地回环网络中的报文RawCap
一.下载地址: 官网地址:https://www.netresec.com/?page=RawCap 百度云:链接:https://pan.baidu.com/s/1mWCOTRF5XicuJitBA ...
- google protobuf学习笔记:windows下环境配置
欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/45371743 protobuf的使用和原理,请查看:http:/ ...
- 原创 C++应用程序在Windows下的编译、链接:第一部分 概述
本文是对C++应用程序在Windows下的编译.链接的深入理解和分析,文章的目录如下: 我们先看第一章概述部分. 1概述 1.1编译工具简介 cl.exe是windows平台下的编译器,link.ex ...
- C++应用程序在Windows下的编译、链接(一)概述
C++应用程序在Windows下的编译.链接(一)概述 本文是对C++应用程序在Windows下的编译.链接的深入理解和分析,文章的目录如下: 我们先看第一章概述部分. 1概述 1.1编译工具简介 c ...
随机推荐
- STL--set
set-概述: 集合Set是一个容器,它其中所包含的元素的值是唯一的.集合中的元素按一定的顺序排列,并被作为集合中的实例. 一个集合通过一个链表来组织,其具体实现采用了红黑树的平衡二叉树的数据结构. ...
- html bootstrap 表头固定在顶部,表列 可以自由滚动的效果
该效果主要是依照 bootstrap 的一个样式,class="navbar-fixed-top"; 参考网址为:http://v3.bootcss.com/components/ ...
- NEU校园网登录器
http://www.cnblogs.com/weidiao/p/5124106.html 改自学长的博客. 我们的目标是写一个程序实现自动登录校园网.而这基于的是表单的post机制. 输入校园网网址 ...
- Linux crontab 定时任务
http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html 19. crontab 定时任务 通过crontab 命令,我们 ...
- Object Pascal 数据类型
数据类型与定义变量 Object Pascal 语言的最大特点是对数据类型的要求非常严谨.传递给过程或函数的参数值必须与形参的类型一致.在Object Pascal 语言中不会看到像C 语言编译器提 ...
- active developer path ("") does not exist
pod update --verbose --no-repo-update 出现的错误. 解决:在终端中修改你的CommandLine Tools的位置: xcode-select -switch / ...
- ajax发布评论 、显示评论
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...
- Maven clean时候出现异常
首先我使用IDEA创建一个空的project,在这个空的project中创建了一个maven module,然后将这个module打包之后,使用maven clean这个target 的时候报错,如下 ...
- 淘宝封装的一款ui 非常不错
好用的淘宝ui http://m.sui.taobao.org/demos/ 手机端访问地址
- JavaScript的事件对象_鼠标事件
鼠标事件是 Web 上面最常用的一类事件,毕竟鼠标还是最主要的定位设备.那么通过事件对象可以获取到鼠标按钮信息和屏幕坐标获取等. 一.鼠标按钮 只有在主鼠标按钮被单击时(常规一般是鼠标左键)才会触发 ...