Deterministic debugging with rr record-replay. Use when debugging crashes, ASAN faults, or when reverse execution is needed...
rr provides deterministic record-replay debugging with full reverse execution capabilities.
Record: rr record <program> [args]
Sandbox exemption (documented decision): rr needs ptrace and perf counters, which libexec/raptor-run-sandboxed denies, so recording runs the untrusted binary unsandboxed — behavior observed under earlier sandboxed runs says nothing about what the payload does with this ambient authority. Keep the recorded invocation to exactly the reproduced crash command (never a broader test suite or build), and treat any unexpected network or filesystem activity during recording as a finding in itself. Replay carries no such residual: it re-executes the recorded trace under gdb, not the binary against the host.
Replay: rr replay -- -nx -iex 'set auto-load off' -iex 'set auto-load safe-path /dev/null' (enters gdb interface with reverse execution). The flags after -- go to gdb and disable auto-load with no trusted directory: the recorded binary is untrusted, and a permissive gdb config (e.g. an operator ~/.gdbinit widening auto-load safe-path) would otherwise execute scripts the binary or its build tree plants (.debug_gdb_scripts, *-gdb.py). Same hardening set as scripts/crash_trace.py — use it on EVERY manual replay.
All standard gdb commands work, plus reverse variants:
reverse-next / rn: Step back over function callsreverse-step / rs: Step back into functionsreverse-continue / rc: Continue backward to previous breakpointreverse-stepi / rsi: Step back one instructionreverse-nexti / rni: Step back over one instructionAfter rr record <crashing-program>:
rr replay -- -nx -iex 'set auto-load off' -iex 'set auto-load safe-path /dev/null'
# In gdb:
reverse-next 100 # Go back 100 steps (adjust N as needed)
# Now step forward to see execution leading to crash:
next
next
...
After rr record <asan-program>:
rr replay -- -nx -iex 'set auto-load off' -iex 'set auto-load safe-path /dev/null'
# In gdb:
bt # View stack trace
up # Issue "up" commands until last app frame (before ASAN runtime)
break *$pc # Set breakpoint at that location
reverse-continue # Go back to last app instruction before ASAN
# Now step forward to see execution leading to fault:
next
next
...
Standard gdb commands work at any point:
print <var>: Print variable valueprint *<ptr>: Dereference pointerx/<format> <address>: Examine memoryx/10xb <addr>: 10 bytes in hexx/s <addr>: String at addressinfo locals: Show local variablesinfo args: Show function argumentslist: Show source code around current locationdisassemble: Show assembly around current locationlayout src: TUI source viewlayout asm: TUI assembly viewset disassemble-next-line on: Show assembly with each stepUse scripts/crash_trace.py to automatically extract execution trace before crash.