C++ Segmentation Fault: Five Causes and Debugging with GDB, LLDB, and ASan
이 글의 핵심
Segfaults come from invalid memory access. Learn the top five causes, how to read core files with GDB/LLDB, and why ASan often beats printf-debugging for line-accurate reports.
Related: undefined behavior · another segfault walkthrough: segmentation fault (checklist).
Introduction: “Segmentation fault (core dumped)”
A segmentation fault is a runtime crash: the OS delivers SIGSEGV (Unix) when your process touches memory it must not (typical cases: null, freed, out of range, read-only).
This article covers:
- Five major causes
- GDB/LLDB on core dumps
- AddressSanitizer
- Quick reference tables
Environments: Examples assume GCC/Clang on Linux/macOS; WSL or VS + ASan on Windows are analogous.
flowchart LR
subgraph cause["Causes"]
N[Null deref]
D[Dangling]
S[Stack overflow]
B[Buffer overrun]
C[Bad cast]
end
subgraph debug["Tools"]
G[GDB/LLDB]
A[ASan]
end
cause --> debug
Table of contents
- What is a segfault?
- Cause 1: null pointer
- Cause 2: dangling / use-after-free
- Cause 3: stack overflow
- Cause 4: buffer overrun
- Cause 5: bad cast
- GDB/LLDB core analysis
- AddressSanitizer
1. What is a segfault?
The kernel maps valid virtual pages for your process. Access outside that (null, freed storage, guard pages, wrong permissions) can trigger a CPU fault → SIGSEGV.
Message:
Segmentation fault (core dumped)
core dumped (when enabled) writes a core file you can open in a debugger.
2. Null dereference
int* p = nullptr;
*p = 42;
Mitigation: check nullptr, use std::optional, design APIs that avoid bare pointers.
3. Dangling pointer / UAF
Returning a pointer to a stack array, or using memory after delete, yields undefined behavior—often a crash.
Prefer std::vector, std::unique_ptr, std::string.
4. Stack overflow
Infinite recursion or huge stack arrays exhaust the stack.
Fix: base cases, std::vector on the heap, iterative algorithms.
5. Buffer overrun
Raw arrays have no bounds checks; writing past the end can corrupt metadata or hit guard pages.
Use std::vector::at, careful loop bounds, ASan.
6. Bad downcast
static_cast to derived when the object is not actually derived → corrupt vtables / reads → crash. Prefer dynamic_cast for polymorphic types when needed, and check nullptr.
7. GDB / LLDB cores
ulimit -c unlimited
./your_program # crashes
gdb ./your_program core
Useful commands: bt, bt full, frame N, print ptr, info locals.
LLDB: lldb -c core ./your_program.
8. AddressSanitizer
g++ -g -fsanitize=address test.cpp -o test
./test
Typical output includes exact source lines for heap-buffer-overflow, stack-buffer-overflow, heap-use-after-free, etc.
CMake:
target_compile_options(myapp PRIVATE -fsanitize=address -g)
target_link_options(myapp PRIVATE -fsanitize=address)
Quick checklist
| Symptom | Clue | Mitigation |
|---|---|---|
| Null | p == 0 in debugger | Checks / optional |
| Dangling | ASan UAF | Smart pointers |
| Stack | Deep bt repeats | Heap / iteration |
| Overrun | ASan overflow | Bounds / at() |
| Bad cast | Wrong type path | dynamic_cast |
Related posts (internal)
- GDB/LLDB guide
- Sanitizers
- LNK2019
Keywords
Segmentation fault, segfault, SIGSEGV, core dump, GDB, AddressSanitizer, use-after-free
Closing: combine cores + debugger for post-mortems and ASan during development to catch invalid access before it ships.
Search: segfault, C++ null pointer, GDB backtrace, ASan heap-use-after-free