How does OS X generate a crash report?

后端 未结 1 1441
醉酒成梦
醉酒成梦 2021-02-10 08:20

The material available from web, mail-list, books like Mac OS X Internals, and even source code is quite limited.

Now I know that xnu kernel raise an EXC_CRASH,

相关标签:
1条回答
  • 2021-02-10 08:58

    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 none 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>
    

    The XNU kernel code is responsible 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
            }
    
    0 讨论(0)
提交回复
热议问题