การขยายเครื่องมือตรวจสอบหน่วยความจำสำหรับการแก้ไขข้อบกพร่อง C/C++

ใน Chrome 92 เราได้เปิดตัวเครื่องมือตรวจสอบหน่วยความจำ ซึ่งเป็นเครื่องมือสำหรับตรวจสอบบัฟเฟอร์หน่วยความจำเชิงเส้น ในบทความนี้ เราจะพูดถึงวิธีที่เราปรับปรุงเครื่องมือตรวจสอบสำหรับการแก้ไขข้อบกพร่อง C/C++ และปัญหาทางเทคนิคที่พบระหว่างทาง

ต่อไปนี้คือบล็อกโพสต์ที่เกี่ยวข้องบางส่วนหากคุณเพิ่งเริ่มแก้ไขข้อบกพร่อง C/C++ และเครื่องมือตรวจสอบหน่วยความจำ

บทนำ

เครื่องมือตรวจสอบหน่วยความจำมีตัวเลือกการแก้ไขข้อบกพร่องที่มีประสิทธิภาพมากขึ้นสำหรับบัฟเฟอร์หน่วยความจำเชิงเส้น ในกรณีของ C/C++ คุณสามารถตรวจสอบออบเจ็กต์หน่วยความจำ C/C++ ในหน่วยความจำ WebAssembly

การจดจำไบต์ของออบเจ็กต์ท่ามกลางหน่วยความจำ WebAssembly รอบๆ เป็นปัญหา คุณต้องทราบขนาดของออบเจ็กต์และนับไบต์จากจุดเริ่มต้นของออบเจ็กต์ ในภาพหน้าจอด้านล่าง มีการกําหนดค่าไบต์แรกของอาร์เรย์ int32 10 องค์ประกอบ แต่ยังไม่ชัดเจนว่าไบต์อื่นๆ ใดเป็นของอาร์เรย์ หากสามารถจดจำไบต์ทั้งหมดที่เป็นของวัตถุได้ทันทีคงจะดีไม่น้อย

ภาพหน้าจอของเครื่องมือตรวจสอบหน่วยความจำเดิมที่ไฮไลต์ไบต์เดียว

การไฮไลต์ออบเจ็กต์ในเครื่องมือตรวจสอบหน่วยความจำ

ตั้งแต่ Chrome 107 เป็นต้นไป เครื่องมือตรวจสอบหน่วยความจำจะไฮไลต์ไบต์ทั้งหมดของออบเจ็กต์หน่วยความจำ C/C++ ซึ่งจะช่วยให้คุณแยกความแตกต่างระหว่างหน่วยความจำดังกล่าวออกจากหน่วยความจำรอบข้างได้

ภาพหน้าจอของเครื่องมือตรวจสอบหน่วยความจำที่อัปเดตแล้วพร้อมอาร์เรย์ที่ไฮไลต์อย่างสดใส

ดูวิดีโอด้านล่างเพื่อดูการทำงานของเครื่องมือตรวจสอบหน่วยความจำ เมื่อคุณแสดงอาร์เรย์ x ในเครื่องมือตรวจสอบหน่วยความจำ หน่วยความจำที่ไฮไลต์จะปรากฏในเครื่องมือดูหน่วยความจำพร้อมกับชิปใหม่ด้านบน ชิปนี้จะแสดงชื่อและประเภทของหน่วยความจำที่ไฮไลต์ คลิกชิปเพื่อข้ามไปยังหน่วยความจำของวัตถุ เมื่อวางเมาส์เหนือชิป ไอคอนกากบาทจะปรากฏขึ้น ให้คลิกไอคอนดังกล่าวเพื่อนำไฮไลต์ออก

เมื่อคุณเลือกไบต์นอกออบเจ็กต์ที่ตรวจสอบอยู่ ระบบจะปรับโฟกัสการไฮไลต์ออกเพื่อไม่ให้รบกวนคุณ หากต้องการโฟกัสอีกครั้ง ให้คลิกไบต์ของวัตถุหรือชิปอีกครั้ง

การรองรับการไฮไลต์ออบเจ็กต์ไม่ได้จํากัดอยู่ที่อาร์เรย์เท่านั้น นอกจากนี้ คุณยังตรวจสอบสตรูคเจอร์ ออบเจ็กต์ และพอยน์เตอร์ได้ด้วย การเปลี่ยนแปลงเหล่านี้ช่วยให้คุณสำรวจหน่วยความจำของแอป C/C++ ได้ง่ายกว่าที่เคย

หากอยากลองใช้ คุณจะต้องดำเนินการต่อไปนี้

  • มี Chrome 107 ขึ้นไป
  • ติดตั้งส่วนขยาย C/C++ DWARF
  • เปิดใช้การแก้ไขข้อบกพร่อง DWARF ใน DevTools > การตั้งค่า การตั้งค่า > การทดสอบ > การแก้ไขข้อบกพร่อง WebAssemble: เปิดใช้การรองรับ DWARF
  • เปิดหน้าสาธิตนี้
  • ทำตามวิธีการในหน้า

ตัวอย่างการแก้ไขข้อบกพร่อง

ในส่วนนี้ เราจะดูข้อบกพร่องตัวอย่างเพื่อแสดงให้เห็นวิธีใช้เครื่องมือตรวจสอบหน่วยความจำสำหรับการแก้ไขข้อบกพร่อง C/C++ ในตัวอย่างโค้ดด้านล่าง นักเขียนโปรแกรมสร้างอาร์เรย์จำนวนเต็มและตัดสินใจใช้การดำเนินการเกี่ยวกับพอยน์เตอร์เพื่อเลือกองค์ประกอบสุดท้าย ขออภัย นักเขียนโปรแกรมทําผิดพลาดในการคำนวณพอยน์เตอร์ และตอนนี้โปรแกรมพิมพ์ค่าที่ไร้ความหมายแทนที่จะพิมพ์องค์ประกอบสุดท้าย

#include <iostream>

int main()
{
    int numbers[] = {1, 2, 3, 4};
    int *ptr = numbers;
    int arraySize = sizeof(numbers)/sizeof(int);
    int* lastNumber = ptr + arraySize;  // Can you notice the bug here?
    std::cout <<../ *lastNumber <<../ '\n';
    return 0;
}

นักเขียนโปรแกรมหันมาใช้เครื่องมือตรวจสอบหน่วยความจำเพื่อแก้ไขข้อบกพร่อง คุณสามารถทำตามการสาธิตนี้ ก่อนอื่น นักเรียนจะตรวจสอบอาร์เรย์ในเครื่องมือตรวจสอบหน่วยความจำ และพบว่าอาร์เรย์ numbers มีเฉพาะจำนวนเต็ม 1, 2, 3 และ 4 ตามที่คาดไว้

ภาพหน้าจอของเครื่องมือตรวจสอบหน่วยความจําที่เปิดอยู่พร้อมอาร์เรย์ int32 ที่ตรวจสอบ องค์ประกอบอาร์เรย์ทั้งหมดจะไฮไลต์

จากนั้น นักเรียนจะแสดงตัวแปร lastNumber จากแผงขอบเขต และสังเกตว่าเคอร์เซอร์ชี้ไปยังจำนวนเต็มนอกอาร์เรย์ เมื่อทราบข้อมูลนี้ นักเขียนโปรแกรมจึงพบว่าตนนับออฟเซตของตัวชี้ผิดที่บรรทัด 8 ค่าควรเป็น ptr + arraySize - 1

ภาพหน้าจอของเครื่องมือตรวจสอบหน่วยความจำที่เปิดอยู่ซึ่งแสดงหน่วยความจำที่ไฮไลต์ซึ่งชี้โดยพอยน์เตอร์ชื่อ &quot;lastNumber&quot; หน่วยความจำที่ไฮไลต์อยู่หลังไบต์สุดท้ายของอาร์เรย์ที่ไฮไลต์ไว้ก่อนหน้านี้

แม้ว่านี่จะเป็นตัวอย่างสมมติ แต่ก็มีไว้เพื่อแสดงให้เห็นว่าการไฮไลต์ออบเจ็กต์สื่อให้เห็นขนาดและตำแหน่งของออบเจ็กต์หน่วยความจำได้อย่างมีประสิทธิภาพ ซึ่งจะช่วยให้คุณเข้าใจสิ่งที่เกิดขึ้นภายในหน่วยความจำของแอป C/C++ ได้ดียิ่งขึ้น

วิธีที่เครื่องมือสำหรับนักพัฒนาเว็บระบุสิ่งที่ควรไฮไลต์

ในส่วนนี้ เราจะดูระบบนิเวศของเครื่องมือที่เปิดใช้การแก้ไขข้อบกพร่อง C/C++ โดยเฉพาะอย่างยิ่ง คุณจะได้เรียนรู้ว่า DevTools, V8, ส่วนขยาย C/C++ DWARF และ Emscripten ทําให้การแก้ไขข้อบกพร่อง C/C++ ใน Chrome เป็นไปได้ได้อย่างไร

หากต้องการปลดล็อกประสิทธิภาพการแก้ไขข้อบกพร่อง C/C++ อย่างเต็มรูปแบบในเครื่องมือสําหรับนักพัฒนาเว็บ คุณต้องมี 2 อย่างต่อไปนี้

  • ส่วนขยาย C/C++ DWARF ที่ติดตั้งใน Chrome
  • ไฟล์ซอร์ส C/C++ ที่คอมไพล์เป็น WebAssembly ด้วยคอมไพเลอร์ Emscripten เวอร์ชันล่าสุดตามวิธีการในบล็อกโพสต์นี้

แต่ทำไม V8 ซึ่งเป็นเครื่องมือ JavaScript และ WebAssembly ของ Chrome ไม่รู้วิธีเรียกใช้ C หรือ C++ แต่ Emscripten ซึ่งเป็นคอมไพเลอร์ C/C++ เป็น WebAssembly จะช่วยให้คุณคอมไพล์แอปที่สร้างใน C หรือ C++ เป็น WebAssembly และเรียกใช้ในเบราว์เซอร์ได้

ในระหว่างการคอมไพล์ emscripten จะฝังข้อมูลการแก้ไขข้อบกพร่อง DWARF ไว้ในไบนารี ข้อมูลนี้ช่วยให้ส่วนขยายทราบตัวแปร WebAssembly ที่สอดคล้องกับตัวแปร C/C++ และอื่นๆ ในระดับสูง วิธีนี้จะช่วยให้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์แสดงตัวแปร C++ ให้คุณเห็น แม้ว่า V8 จะใช้งาน WebAssembly อยู่ก็ตาม หากสงสัย โปรดดูบล็อกโพสต์นี้เพื่อดูตัวอย่างข้อมูลการแก้ไขข้อบกพร่อง DWARF

ดังนั้นสิ่งที่จะเกิดขึ้นจริงเมื่อคุณเปิดเผย lastNumber ทันทีที่คุณคลิกไอคอนหน่วยความจํา เครื่องมือสําหรับนักพัฒนาเว็บจะตรวจสอบตัวแปรที่คุณต้องการตรวจสอบ จากนั้นจะค้นหาส่วนขยายเกี่ยวกับประเภทข้อมูลและตําแหน่งของ lastNumber ทันทีที่ส่วนขยายตอบกลับพร้อมข้อมูลดังกล่าว เครื่องมือตรวจสอบหน่วยความจำจะแสดงข้อมูลหน่วยความจำที่เกี่ยวข้องและทราบประเภทของข้อมูลดังกล่าว รวมถึงแสดงขนาดของออบเจ็กต์ได้ด้วย

เมื่อดูที่ lastNumber ในตัวอย่างก่อนหน้านี้ คุณอาจสังเกตเห็นว่าเราได้ตรวจสอบ lastNumber: int * แต่ชิปในเครื่องมือตรวจสอบหน่วยความจำแสดงเป็น *lastNumber: int เกิดอะไรขึ้น เครื่องมือตรวจสอบใช้การอ้างอิงตัวชี้สไตล์ C++ เพื่อระบุประเภทของออบเจ็กต์ที่แสดงให้คุณเห็น หากตรวจสอบเคอร์เซอร์ เครื่องมือตรวจสอบจะแสดงสิ่งที่เคอร์เซอร์ชี้

การเก็บไฮไลต์ไว้ในขั้นตอนโปรแกรมแก้ไขข้อบกพร่อง

เมื่อคุณแสดงออบเจ็กต์ในเครื่องมือตรวจสอบหน่วยความจำและดำเนินการกับโปรแกรมแก้ไขข้อบกพร่อง เครื่องมือตรวจสอบจะยังคงไฮไลต์ไว้หากคิดว่ายังเกี่ยวข้องอยู่ ตอนแรกเราไม่ได้วางแผนที่จะเพิ่มฟีเจอร์นี้ในแผนงาน แต่เราตระหนักได้อย่างรวดเร็วว่าฟีเจอร์นี้ส่งผลเสียต่อประสบการณ์การแก้ไขข้อบกพร่องของคุณ ลองจินตนาการว่าคุณต้องตรวจสอบอาร์เรย์อีกครั้งหลังจากทำแต่ละขั้นตอนเสร็จแล้ว ดังในวิดีโอด้านล่าง

เมื่อโปรแกรมแก้ไขข้อบกพร่องพบจุดหยุดพักใหม่ เครื่องมือตรวจสอบหน่วยความจำจะค้นหา V8 และส่วนขยายอีกครั้งสำหรับตัวแปรที่เชื่อมโยงกับการไฮไลต์ก่อนหน้า จากนั้นจะเปรียบเทียบตำแหน่งและประเภทของวัตถุ หากตรงกัน ข้อความไฮไลต์จะยังคงอยู่ ในวิดีโอด้านบน มีวงวน for เขียนลงในอาร์เรย์ x การดำเนินการเหล่านี้จะไม่เปลี่ยนประเภทหรือตำแหน่งของอาร์เรย์ ดังนั้นอาร์เรย์จะยังคงไฮไลต์อยู่

คุณอาจสงสัยว่าเรื่องนี้ส่งผลต่อเคอร์เซอร์อย่างไร หากคุณมีเคอร์เซอร์ที่ไฮไลต์และกำหนดให้กับวัตถุอื่นอีกครั้ง ตำแหน่งเดิมและตำแหน่งใหม่ของวัตถุที่ไฮไลต์จะแตกต่างกันและไฮไลต์จะหายไป เนื่องจากออบเจ็กต์ที่ชี้ไปใหม่จะอยู่ที่ไหนก็ได้ในหน่วยความจำ WebAssembly และอาจมีความสัมพันธ์เพียงเล็กน้อยกับตำแหน่งหน่วยความจำก่อนหน้า การนําการไฮไลต์ออกจึงชัดเจนกว่าการข้ามไปยังตําแหน่งหน่วยความจําใหม่ คุณสามารถไฮไลต์เคอร์เซอร์อีกครั้งโดยคลิกไอคอนหน่วยความจำของเคีร์เซอร์ในแผงขอบเขต

บทสรุป

บทความนี้อธิบายการปรับปรุงเครื่องมือตรวจสอบหน่วยความจำสำหรับการแก้ไขข้อบกพร่อง C/C++ เราหวังว่าฟีเจอร์ใหม่นี้จะทําให้การแก้ไขข้อบกพร่องหน่วยความจําของแอป C/C++ ง่ายขึ้น หากมีข้อเสนอแนะในการปรับปรุงเพิ่มเติม โปรดแจ้งให้เราทราบโดยรายงานข้อบกพร่อง

สิ่งที่จะเกิดขึ้นหลังจากนี้

ดูข้อมูลเพิ่มเติมได้ที่