【chromium】Crashpad 简介
【chromium】Crashpad 简介
文章目录
参考
Crashpad
- Crashpad 是个客户端 库,用于捕获、存储和传输来自客户端的crash,报告到上游后端收集服务器。
- Crashpad 嵌入在客户端app 中,分为handler、client。
- handler 在一个独立于客户端的进程中运行。它负责在崩溃时对客户端进程的状态进行快照,将其保存为dumps。
- client向 handler 注册,允许它捕获并上传自身的崩溃。
- Crashpad 嵌入在客户端app 中,分为handler、client。
- bug 无处不在,靠用户复现和上报很困难,crash 自动捕获和上报就显得十分重要。
Crashpad handler
- Crashpad handler 被一个嵌入式 app 实例化到一个单独进程,通过为客户端提供IPC方法来注册自己,或者OS 支持。通过对client 进程进行快照,写入database、上传服务器。
- Crashpad handler 支持不同位数的跨位请求和存储。
- 在Windows下,受到操作系统的限制,32位handler 序只能为32位客户端生成崩溃转储,但64位handler 可以获得32位进程的几乎所有细节。
Crashpad client
-
Crashpad client 提供了:向hanlder 注册、crash 时与handler Metadata 交互的能力。
-
嵌入Crashpad ,需要将Crashpad 库链接到一个或多个exe 中,然后client 端进程通过某种IPC或者OS 支持向Handler注册。
-
crash 发生时,metadata 通过 CrashpadInfo 结构传给Handler。
- 每个链接client 库的exe模块,都嵌入了一个 CrashpadInfo 结构,其被client 更新,为client记录任何crash 的状态。
- 下图中,浅蓝色是embedder 、深蓝色是client 模块、绿色是 Crashpad。
设计细节
概况
注册
- windows上有两种注册模式,Handler 都会被client 告知 client 进程空间中一组数据结构的地址。
- 这个结构包括一对Information,一个用于生成crash process 的dump,另一个生成非crash 进程的dump。
- 正常注册模式下:client 通过预先安排的名称连接到一个命名的管道。一个注册请求被写入该管道。在注册过程中,处理程序创建一组事件,将它们复制到注册的客户端,然后在注册响应中返回句柄值。这是一个阻塞的过程。
- (初始处理程序的创建为了避免在处理程序的创建和初始化过程中阻塞客户端的启动,可以使用不同的注册模式来创建处理程序)
- 在这种模式下,客户端创建一组事件句柄并将它们继承到新创建的处理程序进程中。在这种模式下,处理程序通过命令行参数的方式被告知句柄值和Exception Information结构的位置,
捕获异常
-
在Windows上,操作系统会在崩溃线程的上下文中派发异常。
-
为了通知异常处理程序,Crashpad Client 在客户端进程中注册了一个UnhandledExceptionFilter(UEF)。当一个异常流向UEF时,它将异常信息和崩溃线程的ID存储在与 Handler 注册的Exception Information结构中。然后,它设置一个事件句柄,向Handler发出信号,让其处理该异常。
-
注意:
- 如果在异常发生时,崩溃线程的堆栈被粉碎,那么异常就不能被派发。在这种情况下,操作系统会立即终止进程,而处理程序没有机会生成一个崩溃报告。
- 如果一个异常在崩溃的线程中被处理,它将永远不会传播到UEF,因此崩溃报告也不会被生成。这种情况在Windows中经常发生,因为系统库经常会在一个结构化的异常处理程序下调度回调。
- 这种情况在某些系统配置的Window消息调度过程中发生,以及在例如DLL入口点通知过程中发生。
- 在系统和运行时中存在越来越多的情况,在这些情况下,检测到的损坏或非法调用会导致进程的立即终止,在这种情况下,不会产生崩溃报告。
-
Windows错误报告(WER)中存在一种机制,允许客户进程在崩溃进程之外注册处理客户异常。不幸的是,这种机制很难使用,而且没有为上述许多注意事项提供保障。
CrashpadInfo 结构体
- CrashpadInfo结构用于从Client 向 Handler 传递信息,Client 进程中的每个可执行模块都可以包含一个 CrashpadInfo 结构。
- Crash 时,Handler 会抓取Crash 进程中的所有模块以定位所有存在的 CrashpadInfo 结构。CrashpadInfo结构被链接到可执行文件的一个特殊的、命名的部分,Handler 可以很容易地找到它们。
- CrashpadInfo 还包含了一个大小、版本字段,以匹配不同client、Handler 版本。
- CrashpadInfo 包含有:在崩溃 dump 中包含多少内存的上限,一些用于控制处理程序行为的三态标志,一个指向注释字典的指针等等。
Snapshot & Minidump
- Snapshot 是一个代表Crashpad所关心的 机器和操作系统 实体的接口层。快照的不同具体实现可以通过不同的方式得到支持,例如,从崩溃进程的内存表示中,或者例如从minidump的内容中。
- minidump实现负责将快照写入minidump格式的序列化的磁盘文件中。minidump的实现是与操作系统无关的,因为它在一个与操作系统无关的Snapshot 接口上工作。
Crash Dump 的创建
-
快照包含一个启发式选择的完整状态的子集,被从crash 进程中抓取到Handler 进程的内存快照中。
-
通常包含:
- 被加载到崩溃进程中的一系列模块(exe,共享的库)。
- 在崩溃过程中运行的线程的列举,包括每个线程的寄存器内容和堆栈内存内容。
- 进程的操作系统相关状态的选择,如命令行、环境等。
- 从寄存器和堆栈中选择可能被引用的内存。
-
创建 Dump ,crash 进程会被暂停,然后在Handler 进程创建一个snapshot,包括加载到进程中的模块的CrashpadInfo结构,其中的内容被用来控制捕获崩溃Dump的细节程度。
- 快照构造出来会写入一个minidump 文件,并被添加到数据库中。写入minidump文件后,进程就不再暂停了,将被OS或hanlder kill掉。
报告格式与上报
- Crash 报告是以Windows minidump格式记录的,并带有支持Crashpad附加功能的扩展,例如注释等。
- Client 端通过传递给Handler 的命令行,控制收集服务器的URL。让Handler通过Http 上传crashs。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)