Chromium Chronicle #13: Proses Debug Waktu Perjalanan dengan RR

Episode 13: oleh Christian Biesinger di Madison, WI (Maret, 2020)
Episode sebelumnya

Apakah Anda menjalankan pengujian yang sama berulang kali di debugger, mencoba mencari tahu bagaimana kode itu berada dalam kondisi yang buruk? Kami punya alat untuk Anda. Mudah diinstal dan disiapkan, perangkat ini akan merekam jejak eksekusi, dan memberikan kekuatan baru ajaib di gdb. Mundur, berlari mundur, lihat bagian mana variabel mengubah nilainya atau kapan fungsi terakhir dipanggil pada objek (menggunakan titik henti sementara bersyarat).

Di Linux, Anda dapat menggunakan rr. Instal menggunakan sudo apt-get install rr atau dari https://rr-project.org/.

Meskipun tidak didukung secara resmi, tetapi sangat berguna. Cara kerja rr adalah bahwa Anda terlebih dahulu merekam aktivitas, lalu memutar ulang.

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

Dengan mudah, alamat pengaturan waktu dan pointer tetap sama setiap kali Anda memutar ulang pelacakan yang sama. Rekaman aktivitas dapat dijadikan portabel dengan menggunakan rr pack sehingga Anda menyalinnya ke komputer lain dan memutarnya ulang di sana, atau memutar ulang bahkan setelah mengompilasi ulang. Jalankan program Anda menggunakan continue. Anda dapat menggunakan semua Perintah GDB -b, next, watch, dll. Namun, Anda juga dapat menggunakan terbalik-berikutnya (rn), balik-balik (rc), langkah terbalik (rs), sirip balik.

Perintah ini masih mengikuti titik henti sementara yang telah Anda tetapkan. Contoh:

(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*> (

Dalam contoh ini, saya menggunakan --single-process agar lebih praktis, tidak diperlukan. RR dapat melacak beberapa proses; setelah merekam, Anda bisa lihat daftar menggunakan rr ps dan pilih satu untuk diputar ulang dengan rr replay -f PID.

Ada banyak kegunaan RR. Ada perintah lain yang dapat Anda gunakan, seperti kapan harus mencari tahu nomor acara Anda, atau rr replay -M untuk menganotasi stdout dengan ID proses dan nomor peristiwa untuk setiap baris. Lihat situs dan dokumentasi RR untuk mengetahui detail selengkapnya.