エピソード 13: Christian Biesinger、ウィスコンシン州マディソン(2020 年 3 月)
前のエピソード
デバッガで同じテストを何度も実行していませんか?
どうして不正な状態になったのかを
解明しようと思いませんか?便利なツールがあります
インストールと設定が簡単で、実行トレースを記録して、
gdb
に新たな魔法の力が加わります。1 つ後ろに下がる、後ろに下がる、場所を確認する
変数の値が変更された、またはオブジェクトで関数が最後に呼び出された日時
(条件付きブレークポイントを使用)。
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
など。ただし、
逆方向(rn
)、逆連続(rc
)、逆ステップ(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
などです
これにより、各行のプロセス ID とイベント番号で stdout
にアノテーションが追加されます。詳しくは、
RR のウェブサイトとドキュメントをご覧ください。