# Exception Handling

## Introduction

When a thread encounters a fault condition, for example a segfault, execution
is paused and the thread enters exception handling. Handlers which have
registered to receive these exceptions are notified and given a chance to
inspect or correct the condition.

This functionality is commonly used by debuggers or crash loggers, which want
to have a chance to interact with threads before they would otherwise crash.
For applications that just want to track task lifecycles without needing to
intercept crashes, [signals](signals.md) may be a better choice.

## The Basics

Exceptions are handled from userspace by creating an exception channel on a
task (thread, process, or job) with the [`zx_task_create_exception_channel()`]
system call. The created handle is a standard Zircon
[channel](/docs/reference/kernel_objects/channel.md), but is created read-only so can only be used
for receiving exception messages.

When an exception occurs, the thread is paused and a message containing a
`zx_exception_info_t` and an exception handle is sent to the channel. The
lifetime of the exception is bound to the lifetime of this exception handle, so
when the receiver is done processing, closing this exception handle will resume
the exception. This exception handle is non-copyable, meaning that at any given
time, there is only one handler for this exception.

By default, closing an exception handle will keep the thread paused and send
the exception to the next handler. If the receiver has corrected the exception
and wants the thread to resume execution instead, it can change the exception
state to `ZX_EXCEPTION_STATE_HANDLED` via [`zx_object_set_property()`] before
closing.

## Exception Handles

Exception handles behave similarly to suspend tokens by keeping the thread
paused until they are closed. Additionally, exception handles have functions
to help receivers process the exception:

* [`zx_object_set_property()`] with `ZX_PROP_EXCEPTION_STATE` to set behavior
  on handle close
* [`zx_exception_get_thread()`] to get a handle to the exception thread
* [`zx_exception_get_process()`] to get a handle to the exception process
  (process or job exception channels only)

Task handles retrieved from exceptions will have the same rights as the task
originally passed into [`zx_task_create_exception_channel()`].

### Example

This simple example creates an exception channel and loops reading exceptions
until the task closes.

```cpp
void ExceptionHandlerLoop(zx_handle_t task) {
  // Create the exception channel.
  uint32_t options = 0;
  zx_handle_t channel;
  zx_status_t status = zx_task_create_exception_channel(task, options,
                                                        &channel);
  // ... check status ...

  while (true) {
    // Wait until we get ZX_CHANNEL_READABLE (exception) or
    // ZX_CHANNEL_PEER_CLOSED (task terminated).
    zx_signals_t signals = 0;
    status = zx_object_wait_one(channel,
                                ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                                ZX_TIME_INFINITE, &signals);
    // ... check status ...

    if (signals & ZX_CHANNEL_READABLE) {
      // Read the exception info and handle from the channel.
      zx_exception_info_t info;
      zx_handle_t exception;
      status = zx_channel_read(channel, 0, &info, &exception, sizeof(info), 1,
                               nullptr, nullptr);
      // ... check status ...

      // Send the exception out to some other function for processing, which
      // returns true if the exception has been handled and we can resume the
      // thread, or false to pass the exception to the next handler.
      bool handled = process_exception(info, exception);
      if (handled) {
        uint32_t state = ZX_EXCEPTION_STATE_HANDLED;
        status = zx_object_set_property(exception, ZX_PROP_EXCEPTION_STATE,
                                        &state, sizeof(state));
        // ... check status ...
      }

      // Close the exception to finish handling.
      zx_handle_close(exception);
    } else {
      // We got ZX_CHANNEL_PEER_CLOSED, the task has terminated.
      zx_handle_close(channel);
      return;
    }
  }
}
```

## Exception Types

At a high level there are two types of exceptions: architectural and synthetic.
Architectural exceptions are things like a segfault (e.g., dereferencing the
NULL pointer) or executing an undefined instruction. Synthetic exceptions are
things like thread start/stop notifications or
[policy violations](/docs/reference/syscalls/job_set_policy.md).

Architectural and policy exceptions are considered fatal, and will cause the
process to be killed if they are unhandled. Debugger-only exceptions - thread
start/stop and process start - are informational and will continue execution
normally even if the thread isn't explicitly resumed. These exceptions are
meant to give a debugger a chance to react to these lifetime events correctly,
as the corresponding thread will be paused until the exception is resumed.

Exception types are defined in
[`<zircon/syscalls/exception.h>`](/zircon/system/public/zircon/syscalls/exception.h).

## Exception Channel Types

Exception channels have different characteristics depending on the task type and
whether the `ZX_EXCEPTION_CHANNEL_DEBUGGER` flag is passed to
[`zx_task_create_exception_channel()`]. The table below summarizes the
differences between the various channel types:

Channel Type  | `get_thread` | `get_process` | Architectural & Policy Exceptions | Thread Start/Stop Exceptions | Process Start Exception
------------- | :----------: | :-----------: | :-------------------------------: | :--------------------------: | :---------------------:
Thread        | X            |               | X                                 |                              |
Process       | X            | X             | X                                 |                              |
Process Debug | X            | X             | X                                 | X                            |
Job           | X            | X             | X                                 |                              |
Job Debug     | X            | X             |                                   |                              | X

The channel type also determines the order in which exception channels will be
given the chance to handle an exception:

1. process debug
2. thread
3. process
4. job (parent job -> grandparent job -> etc)

If there are no remaining exception channels to try, the kernel terminates the
process as if [`zx_task_kill()`] was called. The return code of a process
terminated by an exception is `ZX_TASK_RETCODE_EXCEPTION_KILL`, and can be
obtained with [`zx_object_get_info()`] using `ZX_INFO_PROCESS`.

Each task only supports a single exception channel per type, so for example
given a process with a debug exception channel attached, trying to create
a second debug exception channel will fail, but creating a non-debug channel
will succeed.

### `ZX_EXCP_PROCESS_STARTING` and Job Debugger Channels

The `ZX_EXCP_PROCESS_STARTING` behaves differently than other exceptions.
It is only sent to job debugger exception channels, and is only sent to the
first found handler, essentially assuming `ZX_EXCEPTION_STATE_HANDLED`
regardless of actual handler behavior. This is also the only exception that
job debugger channels receive, making them a special-case handler for just
detecting new processes.

### Process Debugger First

In Zircon the process debugger exception channel is tried first. This is useful
for at least a few reasons:

- Allows "fix and continue" debugging, e.g. if a thread gets a segfault,
  the debugger user can fix the segfault and resume the thread without any
  non-debugger channels seeing the exception.
- Ensures debugger breakpoints get sent directly to the debugger without
  other handlers having to explicitly pass them along.

## Interaction with Task Suspension

Exceptions and thread suspensions are treated separately.
In other words, a thread can be both in an exception and be suspended.
This can happen if the thread is suspended while waiting for a response
from an exception handler. The thread stays paused until it is resumed
for both the exception and the suspension:

```cpp
zx_handle_close(exception);
zx_handle_close(suspend_token);
```

The order does not matter.

## Interaction with Task Kill

[`zx_task_kill()`] stops any exception handling on the task. If it is called on
a thread (or its parent process/jobs) while the thread is in an exception:

- the thread will stop waiting for the current exception handler
- no further exception handlers will receive the exception
- [`zx_exception_get_thread()`] and [`zx_exception_get_process()`] on the
  outstanding exception handle will continue to provide valid task handles
- [`zx_object_set_property()`] to set the exception's state will still return
  `ZX_OK`, though the state won't have any effect since the thread is no longer
  blocking on the handler

Additionally, a killed thread will still send a `ZX_EXCP_THREAD_EXITING`
exception (if a process debug handler is registered), but as above will not
wait for a response from the handler.

Although [`zx_task_kill()`] is generally asynchronous, meaning the thread may
not finish terminating by the time the syscall returns, it does synchronously
stop exception handling such that once it returns, closing an exception handle
will not resume the thread or pass the exception to another handler.

## Signals

[Signals](signals.md) are the core Zircon mechanism for observing state changes
on kernel objects (a channel becoming readable, a process terminating, an event
becoming signaled, etc).

Unlike exceptions, signals do not require a response from an exception handler.
On the other hand signals are sent to whomever is waiting on the thread's
handle, instead of being sent to the exception channel that could be bound to
the thread's process.

A common pattern in Zircon is to have a message loop that waits for signals on
one or more objects and handles them as they come in. To incorporate exception
handling into this pattern, use [`zx_object_wait_async()`] to wait for
`ZX_CHANNEL_READABLE` (and optionally `ZX_CHANNEL_PEER_CLOSED`) on the
exception channel:

```cpp
zx_handle_t port;
zx_status_t status = zx_port_create(0, &port);
// ... check status ...

// Start waiting on relevant signals on the exception channel.
status = zx_object_wait_async(exception_channel, port, kMyExceptionKey,
                              ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, 0);
// ... check status ...

// ... add other objects to |port| with wait_async() ...

while (1) {
  zx_port_packet_t packet;
  status = zx_port_wait(port, ZX_TIME_INFINITE, &packet);
  // ... check status ...

  if (packet.key == kMyExceptionKey) {
    if (packet.signal.observed & ZX_CHANNEL_READABLE) {
      // ... extract exception from |exception_channel| and process it ...

      // wait_async() is one-shot so we need to reload it to continue
      // receiving signals.
      status = zx_object_wait_async(
          exception_channel, port, kMyExceptionKey,
          ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, 0);
      // ... check status ...
    } else {
      // Got ZX_CHANNEL_PEER_CLOSED, task has terminated.
      zx_handle_close(exception_channel);
    }
  } else {
    // ... handle other objects added to |port| ...
  }
}
```

Note: There is both an exception and a signal for thread termination. The
`ZX_EXCP_THREAD_EXITING` exception is sent first. When the thread is finally
terminated the `ZX_THREAD_TERMINATED` signal is set.

## Comparison with Posix (and Linux)

This table shows equivalent terms, types, and function calls between
Zircon and Posix/Linux for exceptions and the kinds of things exception
handlers generally do.

Zircon                             | Posix/Linux
------                             | -----------
Exception/Signal                   | Signal
ZX_EXCP_*                          | SIG*
zx_task_create_exception_channel() | ptrace(ATTACH,DETACH)
zx_task_suspend()                  | kill(SIGSTOP),ptrace(KILL(SIGSTOP))
zx_handle_close(suspend_token)     | kill(SIGCONT),ptrace(CONT)
zx_handle_close(exception)         | kill(SIGCONT),ptrace(CONT)
zx_task_kill()                     | kill(SIGKILL)
N/A                                | kill(everything_else)
TBD                                | signal()/sigaction()
zx_port_wait()                     | wait*()
various                            | W*() macros from sys/wait.h
zx_exception_info_t                | siginfo_t
zx_exception_context_t             | siginfo_t
zx_thread_read_state()             | ptrace(GETREGS,GETREGSET)
zx_thread_write_state()            | ptrace(SETREGS,SETREGSET)
zx_process_read_memory()           | ptrace(PEEKTEXT)
zx_process_write_memory()          | ptrace(POKETEXT)

Zircon does not have asynchronous signals like `SIGINT`, `SIGQUIT`, `SIGTERM`,
`SIGUSR1`, `SIGUSR2`, and so on.

Another significant difference from Posix is that in Zircon a thread cannot
handle its own exceptions, since Zircon exception handling is a synchronous
operation driven by userspace rather than an asynchronous callback invoked by
the kernel.

## Examples

Zircon code that uses exceptions can be viewed for further examples, including:

- `system/core/svchost/crashsvc`: system-level crash handler
- `system/utest/exception`: exception unit tests
- `system/utest/debugger`: debugger-related functionality unit tests

## See Also

- [`zx_task_create_exception_channel()`]
- [`zx_exception_get_thread()`]
- [`zx_exception_get_process()`]
- [`zx_object_set_property()`]
- [`zx_port_wait()`]

[`zx_exception_get_process()`]: /docs/reference/syscalls/exception_get_process.md
[`zx_exception_get_thread()`]: /docs/reference/syscalls/exception_get_thread.md
[`zx_object_get_info()`]: /docs/reference/syscalls/object_get_info.md
[`zx_object_set_property()`]: /docs/reference/syscalls/object_set_property.md
[`zx_object_wait_async()`]: /docs/reference/syscalls/object_wait_async.md
[`zx_port_wait()`]: /docs/reference/syscalls/port_wait.md
[`zx_task_create_exception_channel()`]: /docs/reference/syscalls/task_create_exception_channel.md
[`zx_task_kill()`]: /docs/reference/syscalls/task_kill.md
