The Chromium Chronicle #13: تصحيح أخطاء السفر عبر الزمن باستخدام RR

الحلقة 13: من تأليف "كريستيان بيسينجر" في مدينة ماديسون في ويسكونسن (آذار/مارس 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 تتبُّع عدة عمليات، وبعد التسجيل، يمكنك عرض قائمة باستخدام rr ps واختيار إحداها لإعادة تشغيلها باستخدام rr replay -f PID.

هناك الكثير من الطرق التي يمكن أن تكون بها RR مفيدة. تتوفّر أوامر أخرى يمكنك استخدامها، مثل وقت معرفة رقم الحدث الذي تتواجد فيه أو rr replay -M لإضافة تعليق توضيحي إلى stdout باستخدام معرّف العملية ورقم الحدث لكل سطر. يمكنك الاطّلاع على موقع RR الإلكتروني والوثائق للحصول على مزيد من التفاصيل.