OS X如何生成崩溃报告?

时间:2012-02-13 01:35:00

标签: macos kernel crash-reports xnu

网页,邮件列表, Mac OS X Internals 等书籍提供的资料,甚至源代码都非常有限。

现在我知道xnu内核引发了一个EXC_CRASH,通知启动后启动“Problem Reporter.app”(之前是Crash Reporter.app)。这个应用程序是使用一些调试界面来生成崩溃报告,还是内核已经生成报告,只是通知应用程序打开已经生成的报告?

1 个答案:

答案 0 :(得分:9)

每个Mach线程和/或任务(实现BSD层进程的底层内核对象)都有异常端口。三个端口级别可用:线程,任务和主机。当发生异常时,会发送Mach消息 - 首先发送到线程端口,然后 - 如果没有人捕获它 - 任务'S',最后是主机。如果获得端口,则可以捕获异常,对其进行调试(与OS X上的gdb一样)或生成故障转储(与Crash Reporter一样)。具体来说,launchd - 所有OS X系统任务的父级 - 注册其异常端口,因此它获取消息,然后触发CrashReporter(正如您从launchd的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就是这样做的:

  /* 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
        }