第 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 命令 -b
、next
、watch
等。但是,您也可以使用 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 -M
,或者使用 rr replay -M
为 stdout
添加每行的进程 ID 和事件编号的注解。如需了解详情,请参阅 RR 网站和文档。