# Understanding magic-trace Trace Scope: Userspace, Kernel, and Combined Modes

> Explore the magic-trace trace scope: understand userspace, kernel, and combined modes to control your tracing. Learn how to include kernel instructions with command-line flags.

- Repository: [Jane Street/magic-trace](https://github.com/janestreet/magic-trace)
- Tags: deep-dive
- Published: 2026-05-24

---

**The magic-trace trace scope determines whether the tool records user-mode instructions, kernel-mode instructions, or both, with the enum defined in [`src/trace_scope.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_scope.ml) and controlled via command-line flags like `-trace-include-kernel`.**

The `janestreet/magic-trace` repository provides granular control over execution visibility through its **trace scope** configuration. By selecting the appropriate mode, you can isolate application-level performance issues or capture the complete picture including kernel activity such as page faults and system calls.

## What Is the magic-trace Trace Scope?

The trace scope is an enumerated type defined in [[`src/trace_scope.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_scope.ml)](https://github.com/janestreet/magic-trace/blob/master/src/trace_scope.ml) that determines which CPU privilege level gets recorded during a tracing session. The OCaml definition exposes three distinct variants:

```ocaml
type t =
  | Userspace
  | Kernel
  | Userspace_and_kernel
[@@deriving sexp_of, compare, equal]

```

This type drives the entire tracing pipeline, from command-line parsing in [[`bin/magic_trace_bin.ml`](https://github.com/janestreet/magic-trace/blob/main/bin/magic_trace_bin.ml)](https://github.com/janestreet/magic-trace/blob/master/bin/magic_trace_bin.ml) to runtime validation in [[`src/trace_writer.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_writer.ml)](https://github.com/janestreet/magic-trace/blob/master/src/trace_writer.ml).

## Available Trace Scope Values

`magic-trace` supports three mutually exclusive tracing modes, each mapping to a specific variant of the `Trace_scope.t` enum:

- **Userspace**: Records only user-mode instructions. This is the **default** behavior when you run `magic-trace` without additional flags.

- **Kernel**: Records only kernel-mode instructions. This scope requires root privileges and is activated by the `-trace-kernel-only` flag.

- **Userspace_and_kernel**: Records **both** user-mode and kernel-mode instructions in a single coherent timeline. This combined scope requires root and is enabled via the `-trace-include-kernel` flag.

The mapping between flags and enum values is registered in [`src/trace_scope.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_scope.ml) through the `commands_and_docs` list:

```ocaml
let commands_and_docs =
  [ ( Userspace_and_kernel, "trace-include-kernel",
      "Trace userspace and the kernel. Requires root." )
  ; ( Kernel, "trace-kernel-only",
      "Trace the kernel and do not trace userspace. Requires root." )
  ]

```

## How to Select a Trace Scope

You can specify the trace scope via command-line interface when attaching to a process or through the OCaml API when integrating `magic-trace` into custom tooling.

### Command-Line Usage

To trace both userspace and kernel activity, pass the `-trace-include-kernel` flag:

```bash
magic-trace attach -pid <pid> -trace-include-kernel

```

For kernel-only tracing, use `-trace-kernel-only` instead:

```bash
magic-trace attach -pid <pid> -trace-kernel-only

```

### OCaml API Integration

When invoking `magic-trace` programmatically, pass the scope variant directly to the tracing functions. The test suite demonstrates this pattern in [[`test/page_fault.ml`](https://github.com/janestreet/magic-trace/blob/main/test/page_fault.ml)](https://github.com/janestreet/magic-trace/blob/master/test/page_fault.ml):

```ocaml
let%map () = Perf_script.run ~trace_scope:Userspace_and_kernel "my_program.perf"

```

## Runtime Enforcement and Validation

The selected scope is strictly enforced during event processing. In [`src/trace_writer.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_writer.ml) (lines 1186‑1192), the code validates that incoming events match the permitted trace scope, particularly when handling system calls and hardware interrupts:

```ocaml
[ [ Trace_scope.Userspace_and_kernel ]
; (if [%compare.equal: Event.Kind.t] kind Hardware_interrupt then [ Kernel ] else [])
]
|> List.concat
|> assert_trace_scope t outer_event

```

This assertion ensures that kernel events are only processed when the current scope explicitly allows them, preventing data corruption in traces configured for userspace-only recording.

## Why Trace Both Domains?

Selecting **Userspace_and_kernel** provides critical visibility into hidden latency sources. Kernel execution includes page-fault handling, system-call processing, and interrupt service routines that often account for unpredictable delays in user-level applications. By tracing both domains simultaneously, you obtain a unified timeline showing exactly how kernel activity interleaves with your application code.

## Summary

- The **magic-trace trace scope** enum in [`src/trace_scope.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_scope.ml) defines three modes: `Userspace`, `Kernel`, and `Userspace_and_kernel`.
- **Userspace** is the default mode and requires no special privileges.
- **Kernel** and **Userspace_and_kernel** modes require root access and are activated via `-trace-kernel-only` and `-trace-include-kernel` respectively.
- Runtime validation in [`src/trace_writer.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_writer.ml) ensures events match the selected scope, particularly for system calls and hardware interrupts.
- Combined tracing reveals kernel-level latency that impacts user-space performance.

## Frequently Asked Questions

### What is the default trace scope in magic-trace?

The default scope is **Userspace**, which records only user-mode instructions. This requires no special privileges and is active when you run `magic-trace` without the `-trace-include-kernel` or `-trace-kernel-only` flags.

### Do I need root privileges to trace kernel activity?

Yes. Both the **Kernel** (`-trace-kernel-only`) and **Userspace_and_kernel** (`-trace-include-kernel`) scopes require root access because capturing kernel-mode execution involves privileged CPU instructions and access to kernel memory space.

### How do I enable combined userspace and kernel tracing?

Pass the `-trace-include-kernel` flag when running `magic-trace attach`. This sets the trace scope to `Userspace_and_kernel`, enabling the tool to record both application code and kernel activity such as page faults and system calls in a single trace file.

### Where is the trace scope validated during execution?

The scope is validated in [`src/trace_writer.ml`](https://github.com/janestreet/magic-trace/blob/main/src/trace_writer.ml) around lines 1186-1192. The code uses `assert_trace_scope` to verify that incoming events (especially syscalls and hardware interrupts) are permitted under the current scope configuration, ensuring data integrity across different tracing modes.