Я хочу использовать Порты исключений Маха для обработки исключений для всех задач (процессов), работающих в macOS.Насколько я понимаю, host_set_exception_ports
будет использоваться в этом случае.Однако host_set_exception_ports
возвращает KERN_NO_ACCESS
( код ошибки 8 ), даже когда я выполняю свою программу с sudo
.Мой экспериментальный код работает для обработки исключений для одной задачи с использованием task_set_exception_ports
.
. Я уже рассмотрел код ядра Mach из host_set_exception_ports
.Существует единственная строка кода , где KERN_NO_ACCESS
возвращается из функции.У меня немного трудное время, чтобы понять, что там происходит.Кажется, код ядра проверяет маску исключения, которую я передаю host_set_exception_ports
.Я тестировал с разными масками исключений, но всегда получал один и тот же отрицательный результат.
Мои вопросы: Означает ли это, что существует общее ограничение на использование host_set_exception_ports
в приложении из пользовательского пространства?Если нет, то как мне настроить порты исключений хоста для получения общесистемных исключений в моем приложении?
Следующая программа является минимальным примером, демонстрирующим поведение, и в противном случае она мало используется.Используйте gcc example.c
для компиляции программы и sudo ./a.out
для ее запуска.
#include <mach/mach.h>
#include <stdio.h>
#include <stdlib.h>
void catchMachExceptions() {
mach_port_t exception_port;
kern_return_t rc;
rc = mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&exception_port);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to allocate exception port: %d\n", rc);
exit(-1);
}
rc = mach_port_insert_right(mach_task_self(),
exception_port,
exception_port,
MACH_MSG_TYPE_MAKE_SEND);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to insert right: %d\n", rc);
exit(-1);
}
rc = host_set_exception_ports(mach_host_self(),
EXC_MASK_ALL,
exception_port,
EXCEPTION_STATE_IDENTITY,
MACHINE_THREAD_STATE);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to set exception: %d\n", rc);
exit(-1);
}
}
int main(int argc, char **argv) {
catchMachExceptions();
}