Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

หา Segmentation Fault ใน C/C++ ด้วย GDB Debugger


Segmentation Fault (Segfault) เป็น Runtime Error ที่เกิดจาก Memory Access Violation เช่น เข้าถึง Array Index ผิด, Dereference Null Pointer, Stack Overflow, หรือ เขียนทับ Memory ที่ Protected

ตัวอย่างโค้ดที่ทำให้เกิด Segfault

#include <stdio.h>

int main() {
    int* ptr = NULL;
    *ptr = 1; // พยายามเขียนที่ Address 0 (Invalid Memory)
    printf("%p\n", ptr);
    return 0;
}

ขั้นตอน Debug ด้วย GDB

1. คอมไพล์ด้วย Flag -g (Debug Symbols)

gcc -g segfault_example.c -o segfault_example

2. รันโปรแกรมให้ Crash ก่อน (เพื่อสร้าง Core Dump)

./segfault_example
# Segmentation fault (core dumped)

หมายเหตุ: ถ้าไม่มี Core Dump ตรวจสอบ ulimit -c unlimited

3. เปิด GDB พร้อม Core Dump

gdb ./segfault_example core

4. ใช้คำสั่ง run หรือ r

(gdb) r
Starting program: /path/segfault_example
Program received signal SIGSEGV, Segmentation fault.
0x000055555555465e in main () at segfault_example.c:5
5       *ptr = 1; // trying to access unknown memory location
(gdb)

GDB แสดงบรรทัดที่ Error เกิดขึ้นพอดี (บรรทัดที่ 5)

5. คำสั่ง GDB ที่มีประโยชน์

คำสั่งคำอธิบาย
bt / backtraceแสดง Call Stack (Function Call Hierarchy)
info localsแสดงค่าตัวแปร Local ทั้งหมด
print ptrแสดงค่าของตัวแปร ptr
listแสดงโค้ดรอบๆ บรรทัดที่ Error
frame Nสลับไป Frame ที่ N ใน Stack
quit / qออกจาก GDB

สาเหตุทั่วไปของ Segfault

  • Null Pointer Dereference: int *p = NULL; *p = 5;
  • Buffer Overflow: เขียนเกินขนาด Array
  • Use After Free: ใช้ Pointer หลัง free() แล้ว
  • Double Free: free() เดียวกัน 2 ครั้ง
  • Stack Overflow: Recursion ลึกเกินไป หรือ Array ใหญ่บน Stack
  • Uninitialized Pointer: Pointer ที่ไม่ได้ Initialize

เครื่องมือเสริม

  • Valgrind: valgrind --leak-check=full ./program - หา Memory Error ได้แม่นยำกว่า
  • AddressSanitizer (ASan): gcc -fsanitize=address -g file.c - Detect ระหว่าง Runtime
  • Core Dump Analysis: coredumpctl gdb (systemd)