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-nextrn)、reverse-contrc)、reverse-steprs)、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 で再生するプロセスを 1 つ選択できます。

RR はさまざまな方法で役立ちます。現在のイベント番号をいつ確認できるかなど、使用できるコマンドは他にもあります。また、rr replay -M を使用して、各行のプロセス ID とイベント番号で stdout にアノテーションを付けることもできます。詳しくは、RR のウェブサイトとドキュメントをご覧ください。