当前位置:首页>Linux>5. Linux系统 RR(Record and Replay)工具重现Linux系统崩溃的调用栈

5. Linux系统 RR(Record and Replay)工具重现Linux系统崩溃的调用栈

  • 2026-10-21 13:28:41
5. Linux系统 RR(Record and Replay)工具重现Linux系统崩溃的调用栈

在 Linux 开发中,调试复杂程序尤其是多线程程序时,复现 Bug 往往非常困难。RR(Record and Replay)是一款由 Mozilla 开发的 用户态程序记录与回放工具,可以精确记录程序执行轨迹,并在回放时可在 gdb 中进行调试,使调试变得可重复和精确。


一、RR 是什么

RR 是一个 轻量级的用户态动态二进制插桩工具,主要功能:

  1. 记录(Record)在程序运行时记录指令执行、系统调用、线程调度顺序等信息。

  2. 回放(Replay)可以在任意时间重复回放程序执行,保证线程调度和指令执行一致,使调试非确定性 Bug(如竞态条件)变得可复现。

  3. 和GDB 一起使用通过 RR 的回放机制,可在 gdb 中精准调试程序,设置断点、观察变量和调用栈,无需担心线程调度导致的不可复现问题。

RR 的核心特点:

特性
描述
可复现性
精准重现多线程和异步事件导致的 Bug
集成调试
可直接在 gdb 中调试回放记录
用户态
不需要修改内核,易于部署
高效
相比完全虚拟化方案性能更好

二、RR 安装

RR 在 Linux 上有官方支持(主要是 Ubuntu/Debian),安装方式如下:

  • Ubuntu/Debian

sudo apt updatesudo apt install rr -y
  • 从源码编译

git clone https://github.com/mozilla/rr.gitcd rrcmake -G "Unix Makefiles" .makesudo make install

安装完成后可验证:

rr --version

三、RR 的基本使用

1. 记录程序执行

rr record ./test_program
  • record 会在后台创建 .rr 目录保存执行轨迹

  • 执行完成后,产生可回放的 trace 文件

2. 回放程序

rr replay
  • 进入 rr 回放模式

  • 可在回放过程中打开 gdb 进行调试:(GDB使用方式见我的 GDB使用指南文章)

(gdb) b main(gdb) c

3. 命令行调试

  • 设置断点

rr replay(gdb) b foo(gdb) c
  • 反向调试(gdb 支持)

(gdb) reverse-step(gdb) reverse-next
  • 查看调用栈

(gdb) bt

4. 调试多线程程序

RR 会记录所有线程调度顺序,并在回放时保证一致,因此即使是竞态条件,也可以稳定复现。


四、RR 实战案例

1. 复现多线程竞态 Bug

假设有一个程序 race_test.c:

#include<stdio.h>#include<pthread.h>int counter = 0;void* thread_func(void* arg){    for(int i=0; i<100000; i++)        counter++;    return NULL;}intmain(){    pthread_t t1, t2;    pthread_create(&t1, NULL, thread_func, NULL);    pthread_create(&t2, NULL, thread_func, NULL);    pthread_join(t1, NULL);    pthread_join(t2, NULL);    printf("Counter = %d\n", counter);    return 0;}

这个程序在不同运行中可能输出不同结果(竞态条件)。

使用 RR 记录:

rr record ./race_test

回放调试:

rr replay(gdb) b main(gdb) c

通过反向调试(reverse-step)可以精确定位哪条指令导致 counter 写入冲突,从而定位竞态条件。


2. 调试崩溃

当程序随机崩溃时:

rr record ./crash_programrr replay
  • 你可以在崩溃位置设置断点,查看崩溃时堆栈、寄存器和变量状态

  • 保证每次调试的执行环境一致,避免“跑一次好、跑一次崩”的问题


五、RR 使用技巧

  1. 只记录指定线程或程序

rr record --threads=1 ./program
  1. 保存历史记录

rr pack /path/to/store
  • 将记录归档,可在其他机器上回放

  1. 与 gdb 高级功能结合

  • 反向调试(reverse-step / reverse-next)

  • 条件断点(break foo if x==5)

  • 内存检查(配合 Valgrind 或 AddressSanitizer)


六、RR 局限性

  1. 仅支持 x86_64 Linux不支持 Windows 或 macOS

  2. 性能开销记录模式会比原程序慢 2~10 倍(取决于程序复杂度)

  3. 内核依赖某些系统调用行为在 RR 中有特定限制,需要最新版内核支持

  4. 大型程序记录空间消耗大对长时间运行或大程序,记录文件可能很大,需要做好磁盘规划


七、总结

RR 是调试多线程、异步或随机崩溃程序的利器,通过记录与回放机制:

  • 精确复现 Bug

  • 支持反向调试

  • 集成 GDB 调试功能

  • 保证程序执行可重复性

结合 Valgrind、ltrace 等工具,作为资深工程师的你可以实现从内存错误、库函数调用到线程竞态问题的全方位分析。

还有许多使用方式见man手册:

最新文章

随机文章