From karellen-rr-mcp
Debug a crash or test failure using rr reverse debugging. Records a command, replays it, and works backwards from the failure to find the root cause.
npx claudepluginhub karellen/claude-plugins --plugin karellen-rr-mcpThis skill uses the workspace's default tool permissions.
Use this skill when the user wants to debug a crash, segfault, test failure, or any bug
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Builds scalable data pipelines, modern data warehouses, and real-time streaming architectures using Spark, dbt, Airflow, Kafka, and cloud platforms like Snowflake, BigQuery.
Builds production Apache Airflow DAGs with best practices for operators, sensors, testing, and deployment. For data pipelines, workflow orchestration, and batch job scheduling.
Use this skill when the user wants to debug a crash, segfault, test failure, or any bug where the cause isn't obvious from reading the code.
rr and gdb must be installed and on PATHperf_event_paranoid must be <= 1: sysctl kernel.perf_event_paranoid-g, preferably -O0 or -Og)Generate a random trace directory name under the project directory to keep traces local
and avoid cluttering ~/.local/share/rr/:
rr_record(command=["./failing_test"], trace_dir="<project>/rr-trace-<random>")
Pass working_directory if the command needs to run from a specific directory.
Pass env for additional environment variables (e.g., {"MALLOC_CHECK_": "3"}).
If the recorded command spawns child processes (test harnesses, build systems, etc.), the default replay targets the root process, which is usually NOT what you want.
rr_ps(trace_dir="<trace>")
Look for the actual program binary in the command column. Use exit codes to identify the crashing process: negative codes indicate signals (-11 = SIGSEGV, -6 = SIGABRT).
rr_replay_start(trace_dir="<trace>", pid=<pid>)
Always pass pid for multi-process recordings.
rr_continue() stops automatically at the signalrr_breakpoint_set(), then rr_continue()rr_breakpoint_set("abort") or rr_breakpoint_set("__assert_fail"), then rr_continue()rr_backtrace() to see the call stackrr_locals() to see local variablesrr_evaluate("expr") to evaluate expressionsrr_select_frame(N) to inspect caller frames without steppingrr_source_lines() to see source code at the current positionThis is the key advantage of rr. From the point where the bug manifests:
rr_next(reverse=True) or rr_step(reverse=True) to walk backwardsrr_watchpoint_set("var") then
rr_continue(reverse=True) to find the exact write that corrupted itrr_checkpoint_save() at interesting points and
rr_checkpoint_restore(id) to jump backrr_when() to note event numbers and rr_run_to_event(N) to jumpFor concurrency bugs:
rr_thread_list() to see all threadsrr_thread_select(id) to switch contextrr_backtrace() and rr_locals()rr_replay_stop()
rr_rm(trace_dir="<trace>")
trace_dir to rr_record. The directory must NOT already exist.rr_rm(). Especially important with project-local
trace directories.rr_breakpoint_set("file.c:100", condition="i == 42") to stop only when specific
conditions hold.