Chromium Chronicle #13:使用 RR 进行时间旅行调试

第 13 集:作者:Christian Biesinger,威斯康星州麦迪逊(2020 年 3 月)
上一集

您是否发现自己在调试程序中反复运行同一测试, 尝试弄清楚代码为何处于不良状态?我们为您准备了一款工具! 易于安装和设置,它会记录执行轨迹, 为gdb提供魔法新力量。后退、倒退、查看哪里 变量更改了值,或者上次对对象调用函数的时间 (使用条件断点)。

在 Linux 上,您可以使用 rr。使用 sudo apt-get install rr 或 (位于 https://rr-project.org/)。

这虽然没有得到官方支持,但非常有用。rr 的运作方式是 您先记录轨迹,然后重放

rr record .../content_shell --no-sandbox  --disable-hang-monitor --single-process
# record the trace. --single-process is optional, see below. The other flags are required.
rr replay # This will replay the last trace
(gdb)       # rr uses GDB to let you replay traces

方便的是,每次重放时时间和指针地址都保持不变 相同的跟踪记录。您可以使用 rr pack 使跟踪记录具有可移植性, 可以将这些文件复制到另一台计算机上,然后在一台计算机上重放 重新编译使用 continue 运行程序。您可以使用 GDB 命令 -bnextwatch 等。不过,您也可以使用 reverse-next (rn)、reverse-cont (rc)、reverse-step (rs)、 reverse-fin

这些断点仍会遵循您已设置的任何断点。例如:

(gdb) c  # Execute to the end
(gdb) break blink::LayoutFlexibleBox::UpdateLayout
(gdb) rc # Run back to the last layout call
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
    this=0x121672224010)
(gdb) # Inspect anything you want here. To find the previous Layout call on this object:
(gdb) cond 1 this == 0x121672224010
(gdb) rc
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
    this=0x121672224010)
(gdb) watch -l style_.ptr_ # Or find the last time the style_ was changed
(gdb) rc
Thread 5 hit Hardware watchpoint 2: -location style_.ptr_

Old value = (const blink::ComputedStyle *) 0x1631ad3dbb0
New value = (const blink::ComputedStyle *) 0x0
0x00007f68cabcf78e in std::__Cr::swap<blink::ComputedStyle const*> (

在此示例中,为简单起见,我使用了 --single-process, 不需要。RR 可以跟踪多个进程;录制结束后,您可以 使用 rr ps 查看列表,然后选择一项以使用 rr replay -f PID 重放。

RR 的作用有很多。您还可以使用其他指令, 例如,查询活动编号或rr replay -Mstdout 添加每行的进程 ID 和事件编号作为注解。请参阅 如需了解详情,请参阅 RR 网站和文档