# Exception Handling

## Introduction

When a thread encounters a fault condition, for example a segfault, execution
is paused and the thread enters exception handling. Handlers that 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. process debug (optionally, if the exception is [`'second-chance'`](#process-debugger-first-and-possibly-again-later))
5. 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... and Possibly Again Later

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.

If an exception has ZX_EXCEPTION_STRATEGY_SECOND_CHANCE set and remains
unhandled after the process exception channel is tried, the process debugger
exception channel will be given a second chance. The utility of this lies in
the case in which a process listens to its own exceptions and uses that
information for correct functioning; in this case, it serves to have debugger
inspect in the event of a failed correction.

## 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
