MapleStory

Something about Crash reporter in different system

通用

这里所描述的都指的是用户态的crash,kernel的crash的处理方式略有区别。本文只是简述crash信息保存的
流程。

在linux系统上,应用异常是通过信号从内核通知上来的,在用户态注册的信号处理函数能够保存一些信息,
在信号处理函数运行完成之后,kernel可能会进行一些core dump,这取决于配置。

当用户态crash时,信号传递给预先注册的signal handler,这时crash尚处于active状态,signal
handler运行在同一个进程里,此时也可以通知外部的进程,例如tombstoned,进行dump操作。

大致需要保存的信息主要来源于1.procfs 2.ptrace 3.logs 4.traces
procfs在进程尚未退出之前都会存在,可以从中保存maps、cmd line、 stat等信息
ptrace系统调用能够查看被监听进程的内存、寄存器.
logs包括 dev/kmsg 的 kernel日志

Android

在Android上使用 debuggerd tombstoned以及crash_dump进行crash事件日志的收集。
tombstoned是一个常驻的daemon,用于crash事件的处理,crash_dump在crash发生时启动,dump其stack以及
register信息,debuggerd充当连接两者的作用。
由于java crash与native crash的处理流程略有差异,这里只介绍native crash的流程
主要流程:
1.bionic库中的linker初始化过程中进行debuggerd客户端的初始化
2.在crash发生时运行预先注册的信号处理函数,设置相关flag,clone 一个进程进行dump,原进程等待dump结束。
3.子进程中运行crash_dump,会fork出新进程,从clone的进程中读取所需的数据.
5.crash_dump将数据写入tombstoned(g_output_fd)
在dump完成后会通知
6.tombstoned生成tombstone文件

Chromium OS‎

Chromium OS‎ 也是基于linux内核,所以应该有着相似的机制.
所有crash的异常从kernel触发,但Chromium os并未使用signal返回到用户态进行处理,而是
1.进行coredump,并将crash进程信息连同coredump一同发送给crash_reporter
这时kernel 2.6.19的新增机制,使用| (pipe symbol) 将core dumps发送到用户进程
refs:
http://man7.org/linux/man-pages/man5/core.5.html
2.当然,应用也可以使用signal机制进行触发,一般使用的是谷歌的breakpad或者crashpad进行收集
这种机制类似与Android的机制,只是信号处理者从debuggerd的hanlder换成了breakapd
3.crash_reporter coredump转换成minidump,并定期上传
4.如果应用自行注册信号处理,并在处理完成之后退出,则不会产生core dump信息,也不会发送给crash_reporter

Fuchsia

Fuchsia 使用名为zircon的内核,所以并不使用signal作为crash的触发源。运行实体也略有差异。
对于一个内核对象,总是会有一个Exception Port,用于处理该对象的异常。
这个对象可以是线程,进程抑或是一个任务。
一个用户态的对象能够通过bind的方式对另一个对象的异常进行监听。
这个过程由系统调用完成-zx_task_bind_exception_port
refs:
https://fuchsia.googlesource.com/zircon/+/master/docs/exceptions.md
所以可以在一个用户态进程里bind所有的进程或者线程异常?

从提交记录来看Google 的CrashPad是支持fuchsia的
refs:
https://chromium-review.googlesource.com/q/+fuchsia+project:crashpad/crashpad,225
可以考虑从其实现中查看一般的crash记录流程。

Comments