Crashpad编译
Crashpad 是由 Google 开发的一个开源的跨平台崩溃报告库,主要用于在应用程序崩溃时收集和提交崩溃信息。通常,我们需要cmake来编译项目,但由于crashpad不使用cmake编译,因此要实现源码编译crashpad,需要编写cmakelists.txt来编译。
git clone github.com/TheAssemblyArmada/crashpad-cmake.git
在cmakelists.txt中添加:
add_subdirectory(crashpad-cmake)
crashpad原理(翻译自官方文档)
Crashpad捕获导致崩溃的异常的详细做法在不同操作系统之间有所不同。
macOS
在macOS上,操作系统将通过设置为客户端进程异常端口的Mach端口通知客户端崩溃的处理程序。由于在macOS上,内核将异常分派到Mach端口,因此在异常发生时,可以完全通过Crashpad处理程序处理异常,而无需在异常发生时在崩溃进程中运行任何代码。
iOS
在iOS上,操作系统将通过Mach异常端口或信号处理程序通知崩溃的处理程序。由于异常在进程内处理,因此生成的是中间转储文件而不是迷你转储。有关iOS进程内处理程序的更多信息,请参阅更多信息。
Windows
在Windows上,操作系统在崩溃线程的上下文中分派异常。为了通知处理程序异常,Crashpad客户端在客户端进程中注册一个UnhandledExceptionFilter(UEF)。当异常传播到UEF时,它将异常信息和崩溃线程的ID存储在注册到处理程序的ExceptionInformation结构中。然后,它设置一个事件句柄以通知处理程序继续处理异常。
注意事项
如果在异常发生时崩溃线程的堆栈被破坏,无法分派异常。在这种情况下,操作系统将立即终止进程,处理程序将无法生成崩溃报告。
如果在崩溃线程中处理异常,它将永远不会传播到UEF,因此不会生成崩溃报告。在Windows中,这在系统库通常会在结构化异常处理程序下分派回调时发生。在某些系统配置中,在Windows消息分派期间以及例如DLL入口点通知期间经常发生这种情况。
在系统和运行时中存在越来越多的条件,检测到的破坏或非法调用导致进程被立即终止,这种情况下将不会生成崩溃报告。
进程外异常处理
在Windows错误报告(WER)中存在一种机制,允许客户端进程注册以处理崩溃进程外的客户端异常。不幸的是,这种机制难以使用,并且对上述许多注意事项并不提供覆盖。详细信息请参阅此处。
Linux/Android
在Linux上,异常被分派为信号发送到崩溃线程。Crashpad信号处理程序将通过套接字向Crashpad处理程序发送消息,通知其崩溃的位置以及从崩溃进程中读取的异常信息。在使用共享套接字连接时,通信完全是单向的。客户端将其转储请求发送到处理程序,然后等待处理程序以SIGCONT响应或超时发生。在使用私有套接字连接时,处理程序可以通过套接字响应以与ptrace代理进程通信。代理进程从崩溃进程派生,对崩溃进程执行ptrace请求,并通过套接字将信息发送到处理程序。