さて、私はそれを理解しました。
マッハ例外を処理するには、関心のある例外のマッハポートを登録する必要があります。次に、メッセージが別のスレッドのポートに到着するのを待ちます。メッセージが到着したら、exc_server()
System.libraryによって実装が提供されている呼び出しを行います。exec_server()
到着したメッセージを受け取り、提供する必要のある3つのハンドラーの1つを呼び出します。catch_exception_raise()
、、catch_exception_raise_state()
またはcatch_exception_raise_state_identity()
に渡した引数によって異なりますtask_set_exception_ports()
。これは、32ビットアプリで行われる方法です。
64ビットアプリの場合、32ビット方式は引き続き機能しますが、ハンドラーで渡されるデータは32ビットに切り捨てられる場合があります。64ビットデータをハンドラーに渡すには、少し余分な作業が必要ですが、これは非常に単純ではなく、私が知る限り、十分に文書化されていません。GDBのソースを調べて、ソリューションに出くわしました。
exc_server()
メッセージがポートに到着したときに呼び出す代わりに、代わりに呼び出す必要がありますmach_exc_server()
。catch_mach_exception_raise()
ハンドラーには、、、、catch_mach_exception_raise_state()
およびも異なる名前を付ける必要がありcatch_mach_exception_raise_state_identity()
ます。ハンドラーのパラメーターは、対応する32ビットのパラメーターと同じです。問題は、mach_exc_server()
その方法が提供されていないことexc_server()
です。の実装を取得するmach_exc_server()
には、MIG(Mach Interface Generator)ユーティリティを使用する必要があります。MIGは、インターフェイス定義ファイルを受け取り、指定したハンドラーにマッハメッセージをディスパッチするサーバー関数を含む一連のソースファイルを生成します。10.5および10.6SDKには、例外メッセージ用のMIG定義ファイル<mach_exc.defs>が含まれており、mach_exc_server()
働き。次に、生成されたソースファイルをプロジェクトに含めれば、準備は完了です。
良い点は、10.6+(およびおそらく10.5)をターゲットにしている場合、32ビットと64ビットの両方に同じ例外処理を使用できることです。MACH_EXCEPTION_CODES
例外ポートを設定するときの例外動作とORするだけです。例外コードは64ビット値として送信されますが、32ビットビルドでは32ビットに切り捨てることができます。
ファイルを取得mach_exc.defs
してソースディレクトリにコピーし、ターミナルを開いてコマンドを使用しましたmig -v mach_exc.defs
。mach_exc.h
これにより、、、mach_excServer.c
およびが生成されmach_excUser.c
ました。次に、これらのファイルをプロジェクトに含め、サーバー関数の正しい宣言をソースファイルに追加し、ハンドラーを実装しました。その後、アプリを作成して、準備が整いました。
まあ、これは最良の説明ではありませんが、うまくいけば、それは他の誰かを助けるでしょう。