How to Add Custom Events (branch-misses, cache-misses) to magic-trace Traces
TL;DR: Supply extra perf events on the command line with --extra-events and magic-trace will parse them, request the kernel to record them via perf_event_open(2), and emit the results as Event_sample entries in the trace file.
magic-trace is Jane Street's open-source execution tracer that uses Linux perf to capture high-fidelity timelines. Adding custom hardware events like branch-misses or cache-misses lets you correlate micro-architectural behavior with specific code regions without recompiling your target or the tracer.
How magic-trace Represents Hardware Events
The internal event model is defined in src/event.ml. Raw counter samples are represented by the Event_sample variant of Event.Ok.Data.t at lines 84–86:
| Event_sample of {
location : Location.t; (* where the event originated *)
count : int; (* sampled count *)
name : Collection_mode.Event.Name.t; (* e.g. "branch-misses" *)
}
The Collection_mode.Event.Name.t type is a thin string wrapper, allowing any perf-compatible event name to be stored and later serialized into the output trace.
Enabling Custom Events via the CLI
magic-trace exposes custom events through the --extra-events flag implemented in src/trace.ml (around line 900). The argument parsing logic feeds the comma-separated list into the Collection_mode module, which produces a list of Collection_mode.Event.t values.
These descriptors are passed to the perf backend in src/perf_tool_backend.ml, which opens the hardware counters using perf_event_open(2) and attaches them to the tracing session. During trace decoding, src/perf_decode.ml (line 609) matches the raw perf output lines via regex and constructs Event_sample records for each sample.
Recording branch-misses and cache-misses
Basic syntax
Pass the event names as a comma-separated list:
magic-trace \
--target <binary> \
--extra-events branch-misses,cache-misses \
--output trace.perfetto
The names are forwarded verbatim to the kernel, so any event listed by perf list is valid.
Setting sampling periods
To reduce overhead or increase granularity, append /period=<N> to any event:
magic-trace \
--target <binary> \
--extra-events branch-misses/period=100,cache-misses/period=200 \
--output trace.perfetto
This syntax follows the format demonstrated in test/demo_extra_events.ml, which prints samples as:
<timestamp> <cpu> <event-name>/period=<N>/u: <count>
Debugging raw perf output
To inspect the raw data before conversion, add --debug-perf:
magic-trace \
--target <binary> \
--extra-events branch-misses/period=50 \
--debug-perf \
--output debug.perfetto
This preserves the intermediate perf script output so you can verify that the kernel is generating samples for your custom events.
Viewing Custom Events in Perfetto
After the run finishes, open the trace in Perfetto. magic-trace emits Event_sample entries that appear as a dedicated track named after the event (e.g., "branch-misses"). Each point on the track represents a sampled count processed by Perf_decode.to_event, allowing you to correlate spikes in branch-misses or cache-misses with specific function executions.
Key Implementation Files
| File | Role |
|---|---|
src/event.ml |
Defines the Event_sample variant (lines 82–86) that stores counter samples. |
src/trace.ml |
Parses the --extra-events CLI argument (around line 900) and wires it to Collection_mode. |
src/perf_decode.ml |
Converts perf output lines into Event_sample records via regex matching at line 609. |
src/perf_tool_backend.ml |
Registers extra events with the kernel using perf_event_open(2). |
test/demo_extra_events.ml |
Example demonstrating extra event output formatting. |
Summary
- Use
--extra-eventsfollowed by comma-separated perf event names to enable hardware counters likebranch-missesandcache-misses. - Append
/period=<N>to set custom sampling frequencies for fine-grained control. - magic-trace stores samples as
Event_samplerecords defined insrc/event.ml. - The backend in
src/perf_tool_backend.mlconfigures the kernel viaperf_event_open(2). - Raw samples are parsed by
src/perf_decode.mland displayed as tracks in the Perfetto UI.
Frequently Asked Questions
What perf events are supported by magic-trace?
Any event name recognized by perf list on your Linux system works, including architectural events like cpu-cycles, instructions, branch-misses, and cache-misses, as well as vendor-specific PMU events. The Collection_mode.Event.Name.t type accepts arbitrary strings, so magic-trace does not maintain a hardcoded allowlist.
How do I change the sampling rate for custom events?
Append /period=<N> to the event name when specifying --extra-events. For example, branch-misses/period=100 instructs the kernel to record one sample every 100 branch misses. Lower values increase granularity but also overhead and trace size.
Where does magic-trace store the raw counter values?
Counter values are stored in the count field of the Event_sample variant defined in src/event.ml at lines 84–86. These records are emitted into the trace output and rendered as data points in the Perfetto timeline.
Can I use custom events without modifying the magic-trace source code?
Yes. The --extra-events flag is exposed in the CLI (src/trace.ml around line 900) specifically to allow users to instrument any perf-supported hardware counter without recompilation. Simply pass the event names on the command line.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →