How does OS X generate a crash report?

后端 未结 1 1444
醉酒成梦
醉酒成梦 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条回答
  •  旧时难觅i
    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:

     MachServices
            
                    com.apple.ReportCrash.DirectoryService
                    
                            DrainMessagesOnCrash
                            All
                            ExceptionServer
                            
                    
            
    

    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)
提交回复
热议问题