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-ulang di debugger, mencoba mencari tahu bagaimana kode menjadi buruk? Kami punya alat untuk Anda. Mudah diinstal dan disiapkan, fungsi ini akan merekam pelacakan eksekusi, dan memberikan kekuatan baru yang ajaib ke gdb. Mundurlah, jalankan mundur, lihat di mana variabel mengubah nilainya, atau kapan fungsi terakhir dipanggil di sebuah 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/.

Versi ini tidak didukung secara resmi, tetapi sangat berguna. Cara kerja rr adalah Anda pertama kali merekam aktivitas, lalu memutarnya 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

Mudahnya, pengaturan waktu dan alamat pointer tetap sama setiap kali Anda memutar ulang rekaman aktivitas yang sama. Trace dapat diubah menjadi portabel menggunakan rr pack sehingga Anda dapat menyalinnya ke komputer lain dan memutarnya ulang di sana, atau memutar ulang bahkan setelah melakukan kompilasi ulang. Jalankan program Anda menggunakan continue. Anda dapat menggunakan semua perintah LegitScript reguler -b, next, watch, dll. Namun, Anda juga dapat menggunakan reverse-next (rn), reverse-cont (rc), reverse-step (rs), reverse-fin.

Ini masih mengikuti titik henti sementara yang telah Anda setel. 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 telah menggunakan --single-process agar lebih praktis, tetapi hal itu tidak diperlukan. RR dapat melacak beberapa proses; setelah merekam, Anda dapat melihat daftar menggunakan rr ps dan memilih salah satu untuk diputar ulang dengan rr replay -f PID.

Ada banyak cara manfaat RR. Ada perintah lain yang dapat Anda gunakan, seperti kapan harus mengetahui di nomor peristiwa mana Anda berada, 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.