Ответ 1
Ну, я понял это.
Чтобы обрабатывать исключения mach, вам необходимо зарегистрировать порт mach для интересующих вас исключений. Затем вы ждете сообщения, которое должно прибыть на порт в другом потоке. Когда приходит сообщение, вы вызываете exc_server()
, реализация которого предоставляется System.library. exec_server()
принимает сообщение, которое прибыло, и вызывает одного из трех обработчиков, которые вы должны предоставить. 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 принимает файл определения интерфейса и генерирует набор исходных файлов, которые включают в себя серверную функцию, которая отправляет сообщения mach обработчикам, которые вы предоставляете. 10.5 и 10.6 SDK включают файл определения MIG < mach_exc.defs > для сообщений об исключениях и будет генерировать функцию mach_exc_server()
. Затем вы включаете сгенерированные исходные файлы в свой проект, и тогда вам хорошо идти.
Хорошо, что если вы нацеливаете 10.6+ (и, возможно, 10.5), вы можете использовать ту же обработку исключений для 32 и 64 бит. Просто ИЛИ поведение исключения с MACH_EXCEPTION_CODES
при настройке портов исключения. Коды исключений будут передаваться как 64-битные значения, но вы можете усечь их до 32 бит в своей 32-битной сборке.
Я взял файл mach_exc.defs
и скопировал его в исходный каталог, открыл терминал и использовал команду mig -v mach_exc.defs
. Это создало mach_exc.h
, mach_excServer.c
и mach_excUser.c
. Затем я включил эти файлы в свой проект, добавил правильное объявление для функции сервера в исходном файле и реализовал мои обработчики. Затем я построил приложение и был готов пойти.
Ну, это не лучшее описание, но, надеюсь, это помогает кому-то другому.