Chromium Chronicle #13: اشکال زدایی در زمان سفر با RR

قسمت 13: توسط کریستین بیزینگر در مدیسون، WI (مارس، 2020)
قسمت های قبلی

آیا متوجه می‌شوید که بارها و بارها همان آزمایش را در دیباگر اجرا می‌کنید و سعی می‌کنید بفهمید که چگونه کد در وضعیت بدی قرار گرفته است؟ ما یک ابزار برای شما داریم! نصب و راه اندازی آسان، یک رد اجرا را ثبت می کند، و این قدرت های جادویی جدیدی به gdb می دهد. به عقب بروید، به عقب اجرا کنید ، ببینید متغیرها کجا مقدارشان را تغییر داده اند یا آخرین بار کی یک تابع روی یک شیء فراخوانی شده است (با استفاده از نقاط شکست شرطی).

در لینوکس می توانید از 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 و غیره استفاده کنید. با این حال، می توانید از reverse-next ( rnreverse-cont ( rcreverse-step ( rsreverse-fin نیز استفاده کنید.

اینها همچنان به هر نقطه شکستی که شما تعیین کرده اید احترام می گذارند. مثلا:

(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 مراجعه کنید.