Chromium Chronicle #13: RR ile Zaman Yolculuğunda Hata Ayıklama

13. Bölüm: Christian Biesinger, Madison, WI'den (Mart 2020)
Önceki bölümler

Hata ayıklayıcıda aynı testi tekrar tekrar çalıştırırken kodun nasıl hatalı bir duruma geçtiğini anlamaya mı çalışıyorsunuz? Size özel bir araç sunuyoruz. Kolay kurulumu ve kurulumu sayesinde, yürütme izlemesi kaydeder ve bu da gdb'a yeni sihirli güçler kazandırır. Geriye doğru ilerleyin, geriye doğru çalıştırın, değişkenlerin değerlerini nerede değiştirdiğini veya bir işlevin bir nesnede en son ne zaman çağrıldığını (koşullu ayrılma noktalarını kullanarak) görün.

Linux'ta rr komutunu kullanabilirsiniz. sudo apt-get install rr kullanarak veya https://rr-project.org/ adresinden yükleyin.

Bu, resmi olarak desteklenmez ancak çok faydalıdır. rr özelliğinin çalışma şekli şu şekildedir: öncelikle bir iz kaydedip bu izi yeniden oynatırsınız.

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

Kolaylık sağlayan bir şekilde, aynı izi her tekrar oynattığınızda zamanlama ve işaretçi adresleri aynı kalır. İzler rr pack kullanılarak taşınabilir. Böylece bunları başka bir makineye kopyalayıp orada yeniden oynatabilir veya yeniden derledikten sonra bile tekrar oynatabilirsiniz. continue kullanarak programınızı çalıştırın. Tüm normal GDB komutlarını (-b, next, watch vb.) kullanabilirsiniz. Bununla birlikte, ters-sonraki (rn), ters-devam (rc), ters-adım (rs), ters-fin seçeneklerini de kullanabilirsiniz.

Bunlar, ayarladığınız ayrılma noktalarına uyar. Örneğin:

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

Bu örnekte, basit olması için --single-process parametresini kullandım, ancak bu gerekli değil. RR birden fazla süreci izleyebilir; kayıttan sonra rr ps kullanarak bir liste görebilir ve rr replay -f PID ile tekrar oynatmak üzere birini seçebilirsiniz.

RR birçok şekilde yararlı olabilir. Hangi etkinlik numarasında olduğunuzu ne zaman öğreneceğiniz veya her satır için işlem kimliği ve etkinlik numarası ile stdout ek açıklama eklemek için rr replay -M gibi başka komutlar da kullanabilirsiniz. Daha fazla bilgi için RR web sitesini ve belgelerini inceleyin.