Macos OSX如何生成崩溃报告?
从web、邮件列表、MacOSX内部等书籍甚至源代码中获得的资料都非常有限Macos OSX如何生成崩溃报告?,macos,kernel,crash-reports,xnu,Macos,Kernel,Crash Reports,Xnu,从web、邮件列表、MacOSX内部等书籍甚至源代码中获得的资料都非常有限 现在我知道xnu内核引发了一个EXC_崩溃,它通知启动者启动“Problem Reporter.app”(前面是CRASH Reporter.app)。此应用程序是否使用某个调试接口生成崩溃报告,或者它的内核是否已经生成了报告并通知应用程序打开已生成的报告?每个Mach线程和/或任务(在其上实现BSD层进程的底层内核对象)都有异常端口。有三个端口级别可用:线程、任务和主机。当异常发生时,会发送一条Mach消息-首先发送到
现在我知道xnu内核引发了一个EXC_崩溃,它通知启动者启动“Problem Reporter.app”(前面是CRASH Reporter.app)。此应用程序是否使用某个调试接口生成崩溃报告,或者它的内核是否已经生成了报告并通知应用程序打开已生成的报告?每个Mach线程和/或任务(在其上实现BSD层进程的底层内核对象)都有异常端口。有三个端口级别可用:线程、任务和主机。当异常发生时,会发送一条Mach消息-首先发送到线程端口,然后-如果没有人捕获到它-任务的,最后是主机。如果您获得端口,您可以捕获异常、调试它(OS X上的gdb也是如此)或生成崩溃转储(崩溃报告器也是如此)。具体地说,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>
mach服务
com.apple.ReportCrash.DirectoryService
拉因森撞车
全部的
例外服务器
XNU内核代码负责在EXC_崩溃时发送消息
/* 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
}
/*如果应该生成内核,请通知崩溃报告器*/
如果(hassigprop(WTERMSIG(rv)、SA|u堆芯)|(p->p|u csflags&CS|u KILLED)!=0)){
/*
*检查PT_DENY_ATTACH的流程的解决方法:
*应退出后Leopard(详情见5431025)。
*/
如果((SIGSEGV==WTERMSIG(rv))&&
(p->p_pptr->p_lflag和p_LNOATTACH)){
转到skipcheck;
}
/*
*Crash Reporter查找信号值,原始异常
*输入,并在代码[0]中输入原始代码的低20位
*(分别为8、4和20位)。代码[1]未经修改。
*/
代码=((WTERMSIG(rv)和0xff)uu_异常和0x0f)uu_代码和0xfffff);
子代码=ut->uu_子代码;
(无效)任务异常通知(EXC故障、代码、子代码)//