การขยายเครื่องมือตรวจสอบหน่วยความจำสำหรับการแก้ไขข้อบกพร่อง 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- Loop ไปยังอาร์เรย์ x การดำเนินการเหล่านี้จะไม่เปลี่ยนประเภทหรือตำแหน่งของอาร์เรย์ จึงยังคงได้รับการไฮไลต์อยู่

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

บทสรุป

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

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

ดูข้อมูลเพิ่มเติมได้จากหัวข้อต่อไปนี้