ตอนที่ 13: โดย Christian Biesinger ในเมดิสัน วิสคอนซิน (มีนาคม 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
แล้วเลือก 1 รายการที่ต้องการเล่นซ้ำด้วย rr replay -f PID
ได้
RR มีประโยชน์หลายอย่างด้วยกัน มีคำสั่งอื่นๆ ที่คุณใช้ได้ เช่น เมื่อต้องการดูว่าคุณอยู่ที่หมายเลขเหตุการณ์ใด หรือ rr replay -M
เพื่อใส่คำอธิบายประกอบ stdout
ด้วยรหัสกระบวนการและหมายเลขเหตุการณ์สำหรับแต่ละบรรทัด ดูรายละเอียดเพิ่มเติมได้ที่เว็บไซต์ RR และเอกสารประกอบ