问题描述
可从网上,邮件列表,诸如 Mac OS X Internals 之类的书籍中获得的材料,甚至包括源代码,都非常有限.
The material available from web, mail-list, books like Mac OS X Internals, and even source code is quite limited.
现在,我知道xnu内核会引发一个EXC_CRASH,它会通知启动以启动问题Reporter.app"(之前是Crash Reporter.app).这个应用程式是使用某种侦错介面来产生当机报告吗,还是它的内核已经在产生报告并只是通知应用程式以开启已经产生的报告?
Now I know that xnu kernel raise an EXC_CRASH, which notify launched to start "Problem Reporter.app" (prior is Crash Reporter.app). Is this app using some debugging interface to generate the crash report, or is it kernel already generating the report and just notify the app to open the already-generated report?
推荐答案
每个Mach线程和/或任务(在其上实现BSD层处理的基础内核对象)都具有异常端口.三个端口级别可用:线程,任务和主机.当发生异常时,将发送Mach消息-首先发送到线程端口,然后发送-如果没有人抓住它,则发送任务的消息,最后发送给主机.如果获得端口,则可以捕获异常,对其进行调试(与OS X上的gdb一样)或生成故障转储(与Crash Reporter一样).具体来说,launched是所有OS X系统任务的父级,注册了它们的异常端口,以便它获取消息,然后触发CrashReporter(如您从Launchd的ReportCrash plist中看到的那样:
Every Mach thread and/or task (the underlying kernel object on top of which the BSD layer process is implemented) has exception ports. three port levels are available: Thread, Task, and host. When an exception occurs, a Mach message is sent - first to the thread port, then - if noone caught it - the task'S, and finally the host. If you obtain the port, you can catch the exception, debug it (as does gdb on OS X) or generate a crash dump (as does Crash Reporter). Specifically, launchd - the parent of all OS X system tasks - registers their exception ports, so it gets the messages, and then triggers CrashReporter (as you can see from the launchd's ReportCrash plist:
<key>MachServices</key>
<dict>
<key>com.apple.ReportCrash.DirectoryService</key>
<dict>
<key>DrainMessagesOnCrash</key>
<string>All</string>
<key>ExceptionServer</key>
<dict/>
</dict>
</dict>
XNU内核代码可用于在EXC_CRASH上发送消息.具体来说,proc_prepareexit可以做到:
The XNU kernel code is resposnsible for sending the message on EXC_CRASH. Specifically, proc_prepareexit does that:
/* If a core should be generated, notify crash reporter */
if (hassigprop(WTERMSIG(rv), SA_CORE) || ((p->p_csflags & CS_KILLED) != 0)) {
/*
* Workaround for processes checking up on PT_DENY_ATTACH:
* should be backed out post-Leopard (details in 5431025).
*/
if ((SIGSEGV == WTERMSIG(rv)) &&
(p->p_pptr->p_lflag & P_LNOATTACH)) {
goto skipcheck;
}
/*
* Crash Reporter looks for the signal value, original exception
* type, and low 20 bits of the original code in code[0]
* (8, 4, and 20 bits respectively). code[1] is unmodified.
*/
code = ((WTERMSIG(rv) & 0xff) << 24) |
((ut->uu_exception & 0x0f) << 20) |
((int)ut->uu_code & 0xfffff);
subcode = ut->uu_subcode;
(void) task_exception_notify(EXC_CRASH, code, subcode); // <-- Sends the msg
}
这篇关于OS X如何生成崩溃报告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!