Обрабатывание исключений Маха в приложении OS X на 64 бита

Я смог зарегистрировать свой собственный порт Маха для получения исключений Маха в моих приложениях, и он работает красиво, когда я нацелен на 32 бита. Однако, когда я нацелен на 64 бита, мой обработчик исключений catch_exception_raise() назван, но массив кодов исключений, который передается обработчику, 32 бита шириной. Это ожидается в сборке на 32 бита, но не в 64 битах.

В случае, где я ловлю EXC_BAD_ACCESS первый код является кодом ошибки, и второй код должен быть адресом отказа. Так как второй код 32 бита шириной, высокие 32 бита адреса отказа на 64 бита являются усеченными.

Я нашел флаг в <mach/exception_types.h> Я могу передать в task_set_exception_ports() названный MACH_EXCEPTION_CODES то, которое от рассмотрения источников Darwin, кажется, управляет размером кодов, передало обработчику. Похоже, что это предназначено, чтобы быть ореадой с поведением, переданным в к task_set_exception_ports().

Однако, когда я делаю это и инициировал исключение, мой порт Маха уведомляется, я звоню exc_server() но мой обработчик никогда не называют, и когда ответное сообщение передают обратно ядру, я получаю поведение исключения по умолчанию.

Я нацелен на 10,6 SDK.

Я действительно желаю, чтобы яблоко зарегистрировало бы этот материал лучше. У кого-либо есть какие-либо идеи?

15
задан Brad S 13 May 2010 в 02:25
поделиться

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 предоставленным вами обработчикам. Пакеты SDK 10.5 и 10.6 включают файл определения MIG для сообщений об исключениях и генерируют функцию 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 . Затем я включил эти файлы в свой проект, добавил правильное объявление для функции сервера в исходный файл и реализовал свои обработчики. Затем я создал свое приложение, и все готово.

Ну, это не лучшее описание, но, надеюсь, поможет кому-то другому.

16
ответ дан 1 December 2019 в 04:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: