I want to use Mach Exception Ports to handle exceptions for all tasks (processes) running on macOS. My understanding is that host_set_exception_ports
is to be used in this case. However, host_set_exception_ports
returns KERN_NO_ACCESS
(error code 8) even when I execute my program with sudo
. My experimental code works to handle exceptions for a single task using task_set_exception_ports
.
I already had a look at the Mach kernel code of host_set_exception_ports
. There is a single line of code where KERN_NO_ACCESS
is returned from the function. I have a bit of a hard time to understand what's going on there. It seems the kernel code checks the exception mask I pass to host_set_exception_ports
. I tested with different exception masks but I always get the same negative result.
My questions: Does this mean there is a general restriction to use host_set_exception_ports
in a user-space application? If not, how would I set the host exception ports to receive system-wide exceptions in my application?
The following program is a minimal example to show the behavior and does not have much use otherwise. Use gcc example.c
to compile the program and sudo ./a.out
to execute it.
#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();
}
host_set_exception_ports
in a user-space application" is yes. – Seibel