AddressSanitizer
ตรวจจับข้อผิดพลาดของหน่วยความจำ
AddressSanitizer เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
AddressSanitizer คืออะไร
AddressSanitizer (เอเอสแซน) เป็นเครื่องมือที่ทำงานบนพื้นฐานของคอมไพเลอร์และตรวจจับข้อผิดพลาดด้านหน่วยความจำขณะโปรแกรมทำงาน ได้แก่ การเข้าถึงนอกขอบเขต การใช้หลังคืนหน่วยความจำ การคืนหน่วยความจำซ้ำ และหน่วยความจำรั่ว เครื่องมือนี้เร็วพอสำหรับการทดสอบในชีวิตประจำวัน
การเปิดใช้เอเอสแซน
เพิ่ม -fsanitize=address ทั้งในขั้นตอนคอมไพล์และลิงก์ และเพิ่ม -g เพื่อให้รายงานอ่านได้ง่าย
g++ -fsanitize=address -g -O1 main.cpp -o app
./appบัฟเฟอร์บนฮีปล้นขอบเขต
เอเอสแซนจะแจ้งเตือนเมื่อมีการอ่านหรือเขียนเลยบัฟเฟอร์ที่จัดสรรไว้ โปรแกรมนี้เขียนข้อมูลเลยไปหนึ่งสมาชิก
#include <cstdlib>
int main() {
int* a = (int*)malloc(3 * sizeof(int));
a[3] = 7; // out of bounds
free(a);
return 0;
}การใช้หลังคืนหน่วยความจำ
การเข้าถึงหน่วยความจำหลังจากคืนหน่วยความจำแล้วถือเป็นพฤติกรรมที่ไม่กำหนดไว้ เอเอสแซนจะแจ้ง heap-use-after-free พร้อมสแตกของตำแหน่งที่คืนและจัดสรรหน่วยความจำ
#include <cstdlib>
int main() {
int* p = (int*)malloc(sizeof(int));
free(p);
*p = 5; // use after free
return 0;
}บัฟเฟอร์บนสแตกล้นขอบเขต
เอเอสแซนยังแทรกการตรวจสอบให้กับอาร์เรย์บนสแตกด้วย จึงตรวจจับการเขียนเลยขอบเขตของบัฟเฟอร์ภายในได้
#include <iostream>
int main() {
int buf[3] = {0, 0, 0};
for (int i = 0; i <= 3; ++i) buf[i] = i; // i==3 overflows
std::cout << buf[0] << "\n";
return 0;
}การอ่านรายงาน
รายงานของเอเอสแซนจะระบุประเภทข้อผิดพลาด ที่อยู่ซึ่งเกิดข้อผิดพลาด และร่องรอยสแตกสำหรับการเข้าถึงที่ผิดพลาด รวมถึงการจัดสรรหรือคืนหน่วยความจำที่เกี่ยวข้อง เฟรมแรกของสแตกมักชี้ไปยังข้อบกพร่องโดยตรง
การตรวจจับหน่วยความจำรั่ว
เอเอสแซนมี LeakSanitizer รวมอยู่ในหลายแพลตฟอร์ม โดยรายงานหน่วยความจำที่ไม่เคยถูกคืนเมื่อโปรแกรมสิ้นสุด พร้อมสแตกของการจัดสรร
#include <cstdlib>
int main() {
int* leaked = (int*)malloc(100); // never freed
return 0;
}ตัวเลือกขณะทำงาน
ปรับพฤติกรรมด้วยตัวแปรสภาพแวดล้อม ASAN_OPTIONS เช่น ASAN_OPTIONS=detect_leaks=1:halt_on_error=0
ต้นทุนด้านประสิทธิภาพ
โดยทั่วไปเอเอสแซนทำให้โปรแกรมช้าลงประมาณ 2 เท่าและใช้หน่วยความจำเพิ่มขึ้น ซึ่งยอมรับได้สำหรับการทดสอบและการผสานรวมอย่างต่อเนื่อง แต่ไม่ควรเปิดใช้ในโปรแกรมรุ่นที่จะนำไปใช้งานจริง
ใช้ร่วมกับการทดสอบ
เรียกใช้การทดสอบหน่วยภายใต้เอเอสแซนในการผสานรวมอย่างต่อเนื่อง ข้อบกพร่องจริงจำนวนมากจะแสดงออกก็ต่อเมื่อการทดสอบเรียกใช้โค้ดขณะเปิดตัวตรวจสอบไว้ ควรมีการกำหนดค่าโปรแกรมสร้างแยกต่างหากสำหรับตัวตรวจสอบ
ไม่ใช่สิ่งทดแทนความระมัดระวัง
เอเอสแซนค้นหาข้อบกพร่องได้เฉพาะเส้นทางของโค้ดที่คุณเรียกใช้จริงเท่านั้น ควรใช้ร่วมกับความครอบคลุมการทดสอบที่ดี เพราะแขนงที่มีข้อบกพร่องแต่ไม่เคยถูกเรียกใช้จะยังคงซ่อนอยู่
ตรวจสอบอย่างรวดเร็ว
ทบทวนวิธีเปิดใช้เอเอสแซน
สรุปทบทวน
คุณได้เรียนรู้ AddressSanitizer
- ตรวจจับการเข้าถึงนอกขอบเขต การใช้หลังคืนหน่วยความจำ การคืนหน่วยความจำซ้ำ และหน่วยความจำรั่ว
- เปิดใช้ด้วย
-fsanitize=address -g - รายงานจะระบุข้อผิดพลาดและแสดงสแตกของการจัดสรรหรือคืนหน่วยความจำ
- ช้าลงประมาณ 2 เท่า เหมาะอย่างยิ่งสำหรับการทดสอบและการผสานรวมอย่างต่อเนื่อง แต่ไม่เหมาะกับรุ่นที่จะนำไปใช้งานจริง
คำถามที่พบบ่อย
บทเรียน “AddressSanitizer” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “AddressSanitizer” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “AddressSanitizer”
ตรวจจับข้อผิดพลาดของหน่วยความจำ คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “AddressSanitizer” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การใช้ gdb และ lldb
- AddressSanitizer
- UBSan และ TSan
- พื้นฐาน Valgrind