How to Attach magic-trace to a Running Process: PID vs. fzf Selection Methods
magic-trace supports two mutually exclusive attachment methods: explicitly supplying comma-separated PIDs via the -pid flag, or using an interactive fzf fuzzy finder that parses running processes from ps output.
The attach subcommand in janestreet/magic-trace enables performance tracing on already-running processes without requiring application restart. This functionality is implemented in src/trace.ml and provides flexibility for both scripted automation and interactive workflows.
Two Methods for Process Attachment
The magic-trace attach command resolves target processes through one of two code paths in the attach_command function. These methods are mutually exclusive—supplying a PID list bypasses the interactive selector entirely.
Explicit PID Specification (-pid Flag)
The PID list method accepts one or more process identifiers as comma-separated integers using the -pid (or -p) flag. The argument parser defines this as optional (Arg_type.comma_separated int), which the code later converts to Pid.t values via Pid.of_int.
In src/trace.ml (lines 6069–6079), the flag definition parses user input:
let pids =
let open Param in
flag "-pid" (optional (Arg_type.comma_separated int))
~doc:"PID Comma-separated process id(s) to attach to"
in
When the flag is present, attach_command maps the integers directly to internal PID representations and proceeds immediately to attach_and_record, skipping all interactive selection logic.
Interactive fzf Fuzzy Selection
When no -pid flag is provided, the system invokes select_pid () (implemented around lines 6048–6084 in src/trace.ml). This function enumerates running processes using the system ps command with specific arguments:
let select_pid () =
let%bind lines =
Shell.run_lines ~prog:"ps" ~args:["x"; "-w"; "--no-headers"; "-o"; "pid,args"] ()
in
(* ... processing logic ... *)
The captured lines are piped to Fzf.pick_one from the bundled fzf library (vendor/fzf/src/fzf.ml). The user selects a line containing both PID and command arguments; the code extracts the first space-delimited token as the target PID.
match choice with
| None -> Deferred.Or_error.error_string "No process selected"
| Some line ->
let pid_str = String.strip line |> String.split ~on:' ' |> List.hd_exn in
return (Pid.of_int (Int.of_string pid_str))
How PID Resolution Works Under the Hood
The attachment orchestration follows a strict flow in attach_command:
let%bind (pids : Pid.t list) =
match pids with
| None -> (* Interactive path *)
select_pid () |> Deferred.Or_error.map ~f:(fun pid -> [ pid ])
| Some pids -> (* Explicit path *)
return (List.map ~f:Pid.of_int pids)
in
attach_and_record opts ~elf ~debug_print_perf_commands ~collection_mode pids
Key implementation details:
- Type Safety: Uses Jane Street's
CorelibraryPid.ttype rather than raw integers, enforced throughPid.of_intconversion. - Duplicate Detection: The code explicitly rejects duplicate PIDs using
List.contains_dupbefore attachment. - Backend Delegation: Resolved PIDs are passed to
Backend.Recording.attach_and_recordinsrc/perf_tool_backend.ml, which handles the actual perf-event attachment.
Usage Examples
Attach to a specific process by PID:
magic-trace attach -pid 1234
magic-trace attach -p 9012
Attach to multiple processes simultaneously:
magic-trace attach -pid 1234,5678,9012
Use interactive fzf selection (requires fzf in $PATH):
magic-trace attach
This presents an interface similar to:
? Choose a process to trace
1234 /usr/bin/python3 my_script.py
5678 /usr/bin/node server.js
9012 /usr/local/bin/my_service --verbose
Error Handling and Edge Cases
The implementation includes specific safeguards:
- Missing fzf: If
Fzf.pick_onecannot locate thefzfexecutable, the system returns an explicit error instructing the user to utilize the-pidflag instead. - Parse Failures: Invalid PID strings trigger immediate
Or_errorfailures before any perf attachment attempts. - Permission Checks: Standard Linux permissions apply; attaching to processes owned by other users requires appropriate privileges (handled at the perf backend level).
Summary
- Explicit attachment uses
-pidor-pwith comma-separated integers, parsed viaArg_type.comma_separated intand converted toPid.tviaPid.of_intinsrc/trace.ml. - Interactive attachment invokes
select_pid (), which executesps x -w --no-headers -o pid,argsand pipes output toFzf.pick_onewhen no PID flag is provided. - Architecture separates CLI parsing (
Command.async_or_error), process enumeration (externalpsutility), and backend attachment (src/perf_tool_backend.ml). - Fzf dependency is optional; missing binaries trigger a clear error message directing users to explicit PID specification.
Frequently Asked Questions
What happens if I specify an invalid PID to magic-trace attach?
The command validates PID conversion early using Pid.of_int and Int.of_string. If the string cannot be parsed as an integer or if the PID refers to a non-existent process, the Or_error monad returns a specific error before attempting any perf attachment, preventing confusing low-level failures.
Can I attach to multiple processes simultaneously with magic-trace?
Yes. The -pid flag accepts comma-separated values (e.g., -pid 1234,5678). The parser splits these into a list of integers, maps each to Pid.t, and passes the entire list to attach_and_record. Note that select_pid () (the fzf method) returns only a single PID.
Is fzf required to use magic-trace attach?
No. While the interactive fuzzy selector provides a convenient user experience, it is strictly optional. If fzf is not installed or not in $PATH, the code explicitly requires the -pid flag. This design ensures magic-trace remains functional in headless or containerized environments.
Where does magic-trace get the process list for fzf selection?
The select_pid function executes the system ps command with arguments ["x"; "-w"; "--no-headers"; "-o"; "pid,args"] using Shell.run_lines. This captures all processes visible to the user, formats them as "PID command" strings, and presents them through the Fzf library for interactive selection.
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 →