The Chromium Chronicle #13: RR के साथ समय-यात्रा डीबगिंग

एपिसोड 13: मैडिसन, WI में क्रिश्चियन बिज़िंगर का गाना (मार्च, 2020)
पिछले एपिसोड

क्या आपको डीबगर में एक ही तरह की जांच बार-बार कर रही है और यह पता करने की कोशिश की जा रही है कि कोड खराब स्थिति में कैसे आया? हमारे पास आपके लिए एक टूल है! यह इंस्टॉल और सेटअप करने में आसान है. यह एक्ज़ीक्यूशन ट्रेस रिकॉर्ड करेगा और इससे 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 के सभी सामान्य निर्देशों -b, next, watch वगैरह का इस्तेमाल भी किया जा सकता है. हालांकि, रिवर्स-अगला (rn), रिवर्स-कॉन्टिन (rc), रिवर्स-स्टेप (rs), रिवर्स-फ़िन का भी इस्तेमाल किया जा सकता है.

आपने जो ब्रेकपॉइंट सेट किए हैं उनके हिसाब से ये सेट किए गए हैं. उदाहरण के लिए:

(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 ps का इस्तेमाल करके एक सूची देखी जा सकती है और rr replay -f PID के साथ फिर से चलाने के लिए, किसी एक सूची को चुना जा सकता है.

आरआर (आरआर) को कई तरीकों से इस्तेमाल किया जा सकता है. ऐसे अन्य निर्देश हैं जिनका इस्तेमाल किया जा सकता है, जैसे कि यह पता कब करना है कि आप किस इवेंट नंबर पर हैं या rr replay -M हर लाइन के लिए प्रोसेस आईडी और इवेंट नंबर के साथ stdout एनोटेट करें. ज़्यादा जानकारी के लिए, आरआर की वेबसाइट और दस्तावेज़ देखें.