Chromium Chronicle #13:使用 RR 進行時間旅行偵錯

第 13 集:由威斯康辛州麥迪遜執導的 Christian Biesinger 製作 (2020 年 3 月)
上一集

您是否在偵錯工具中反覆執行相同的測試,試圖找出程式碼發生不良的狀態?我們提供一項工具讓你使用! 安裝和設定方便簡單,還能記錄執行追蹤記錄,進而為 gdb 提供神奇的新功能。向後執行、向後執行:查看變數變更了其值的位置,或上次在物件上呼叫函式的時間 (使用條件中斷點)。

在 Linux 上,您可以使用 rr。請使用 sudo apt-get install rrhttps://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 等。不過,您也可以使用「反向下一個」 (rn)、反向對比 (rc)、「反向步驟」 (rs)、「反向反向」

這些中斷點仍會遵循您設定的所有中斷點。例如:

(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 網站和說明文件