5

Web、メーリングリスト、Mac OS X Internalsのような書籍、さらにはソースコードから入手できる資料はかなり限られています。

これで、xnu カーネルが EXC_CRASH を発生させ、「Problem Reporter.app」を起動するように通知することがわかりました (以前は Crash Reporter.app でした)。このアプリはデバッグ インターフェースを使用してクラッシュ レポートを生成していますか?それともカーネルが既にレポートを生成しており、既に生成されたレポートを開くようにアプリに通知するだけですか?

4

1 に答える 1

10

すべての Mach スレッドおよび/またはタスク (BSD レイヤー プロセスが実装されている基になるカーネル オブジェクト) には、例外ポートがあります。スレッド、タスク、およびホストの 3 つのポート レベルを使用できます。例外が発生すると、Mach メッセージが送信されます - 最初にスレッド ポートに送信され、次に - 何もキャッチされない場合は - タスクのメッセージに送信され、最後にホストに送信されます。ポートを取得すると、例外をキャッチしてデバッグするか (OS X の gdb と同様)、クラッシュ ダンプを生成できます (Crash Reporter と同様)。具体的には、すべての OS X システム タスクの親である launchd が例外ポートを登録するため、メッセージを取得してから 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
        }
于 2012-09-23T18:56:32.717 に答える