Understanding Mach Tasks, Threads, Processes and Exception Handling on iOS/macOS
The article explains how iOS/macOS uses the XNU kernel's Mach micro‑kernel to represent processes, tasks and threads, describes the relationship between them, classifies hardware and software exceptions, shows how Mach exceptions are translated into Unix signals, and provides practical code examples for capturing both Mach exceptions and signals in a crash‑reporting framework.
Task & Thread & Process
iOS runs on the XNU kernel, which combines a Mach micro‑kernel with BSD services. Each running app instance is a process identified by a PID. In the BSD layer a process contains one or more threads and a corresponding Mach task , which is the kernel’s basic resource container.
Process
A process is the user‑level abstraction of an executable instance. It can join a process group via setpgrp(2) . In BSD, a process also includes internal threads and a Mach task.
Task
A Mach task holds a virtual address space, a port name space and one or more threads. It is similar to a process but provides fewer features (no signals, file descriptors, etc.). The BSD process maps one‑to‑one to a Mach task, which acts only as a resource container.
Thread
Threads are the basic CPU scheduling units. iOS threads are POSIX pthread objects built on top of Mach threads. A Mach thread belongs to a single task and shares the task’s address space.
Questions
1. Task vs. Process : each process has a corresponding Mach task that only contains resources. 2. Process vs. Thread : a thread is the smallest scheduling unit, while a process (or task) is the smallest resource‑allocation unit.
Exception Overview
When an application triggers a hardware exception, execution switches from user mode to kernel mode. The kernel converts the exception into a Mach exception message and sends it through a hierarchy of exception ports: thread → task → host.
Mach Exception Transmission
void exception_trige(exception_type_t exception, mach_excpetion_data_t code, mach_msg_type_number_t codeCnt) {
// thread level
thread = current_thread();
excp = &thread->exc_actions[exception];
kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
if (kr == KERN_SUCCESS) goto out;
// task level
task = current_task();
excp = &task->exc_actions[exception];
kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
if (kr == KERN_SUCCESS) goto out;
// host level
host_priv = host_priv_self();
excp = &host_priv->exc_actions[exception];
kr = exception_deliver(thread, exception, code, codeCnt, excp, mutex);
if (kr == KERN_SUCCESS) goto out;
// if none handled, terminate task
(void)task_terminate(task);
out:
if ((exception != EXC_CRASH) && (exception != EXC_RESOURCE))
thread_exception_return();
return;
}If no handler returns KERN_SUCCESS , the kernel terminates the task.
Mach Exception → Unix Signal Mapping
Mach Exception
Unix Signal
Reason
EXC_BAD_INSTRUCTION
SIGILL
Illegal instruction
EXC_BAD_ACCESS
SIGSEGV / SIGBUS
Invalid memory access
EXC_ARITHMETIC
SIGFPE
Arithmetic error (e.g., divide‑by‑zero)
EXC_EMULATION
SIGEMT
Hardware emulation instruction
EXC_BREAKPOINT
SIGTRAP
Breakpoint / trace
EXC_SOFTWARE
SIGABRT, SIGPIPE, SIGSYS, SIGKILL
Software‑generated exceptions
Software exceptions (e.g., Objective‑C runtime errors) are turned directly into signals without passing through Mach.
Exception Handling Strategies
Two main ways to capture crashes:
Unix Signal handlers (catch all signals such as SIGABRT, SIGSEGV, etc.).
Mach Exception ports combined with Unix signals for hardware exceptions.
Signal‑Based Handler Example
static void ryRegisterSignal(int signal) {
struct sigaction action;
action.sa_sigaction = rySignalHandler;
action.sa_flags = SA_NODEFER | SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(signal, &action, 0);
}
static void rySignalHandler(int signal, siginfo_t *info, void *context) {
NSMutableString *mstr = [[NSMutableString alloc] init];
[mstr appendString:@"Signal Exception:\n"];
[mstr appendString:[NSString stringWithFormat:@"Signal %@ was raised.\n", signalName(signal)]];
// write stack trace, thread info, etc.
[mstr writeToFile:@"/Library/signal.txt" atomically:true encoding:NSUTF8StringEncoding error:nil];
exit(-1);
}After handling, the process exits to avoid a repeat loop.
Mach Exception Handler Skeleton
void setupMachHandler() {
kern_return_t rc;
rc = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &myexceptionPort);
rc = mach_port_insert_right(mach_task_self(), myexceptionPort, myexceptionPort, MACH_MSG_TYPE_MAKE_SEND);
exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION |
EXC_MASK_ARITHMETIC | EXC_MASK_SOFTWARE |
EXC_MASK_BREAKPOINT | EXC_MASK_CRASH;
rc = task_set_exception_ports(mach_task_self(), mask, myexceptionPort,
EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
THREAD_STATE_NONE);
pthread_create(&thread, NULL, exc_handler, NULL);
}
static void *exc_handler(void *ignored) {
Request exc;
exc.Head.msgh_size = 1024;
exc.Head.msgh_local_port = myexceptionPort;
while (true) {
mach_msg_return_t rc = mach_msg(&exc.Head, MACH_RCV_MSG|MACH_RCV_LARGE,
0, exc.Head.msgh_size,
exc.Head.msgh_local_port,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (rc != MACH_MSG_SUCCESS) break;
// process exception, write crash file, etc.
break; // for demo
}
exit(-1);
return NULL;
}If the handler does not exit, the offending thread remains blocked while the rest of the app continues to run.
Key Takeaways
Mach exceptions are the kernel’s low‑level way of reporting hardware faults; they are later translated to Unix signals for compatibility.
Software‑generated crashes (e.g., Objective‑C exceptions) bypass Mach and go straight to signals.
To capture all crashes you need both a Mach‑exception port (for hardware faults) and signal handlers (for software faults such as SIGABRT).
After handling, either re‑raise the signal with raise(signal) or terminate the process with exit(-1) to avoid infinite loops.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.