---
# === IDENTITY ===
id: software/debugging/c-cpp-segfault/2026
canonical_question: "How do I debug segmentation faults in C and C++?"
aliases:
  - "segmentation fault C"
  - "segfault C++"
  - "SIGSEGV debugging"
  - "core dumped segfault"
  - "null pointer dereference C"
  - "GDB segfault backtrace"
  - "Valgrind segfault"
  - "AddressSanitizer segfault"
  - "segmentation fault core dump analysis"
  - "C++ memory access violation"
entity_type: software_reference
domain: software > debugging > c_cpp_segfault
region: global
jurisdiction: global
temporal_scope: 1990-2026

# === VERIFICATION ===
last_verified: 2026-05-17
confidence: 0.95
version: 1.1
first_published: 2026-02-20

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: stable
  last_breaking_change: "GCC 14 (May 2024) — hardware-assisted AddressSanitizer (-fsanitize=hwaddress) enabled by default on x86-64 LAM_U57, lower overhead than classic ASan"
  next_review: 2026-11-13
  change_sensitivity: low

# === AGENT HINTS ===
inputs_needed:
  - key: "language"
    question: "Is this C or C++ code?"
    type: choice
    options: ["C", "C++", "mixed"]
  - key: "platform"
    question: "What OS are you running on?"
    type: choice
    options: ["Linux", "macOS", "Windows"]
  - key: "build_system"
    question: "What compiler are you using?"
    type: choice
    options: ["GCC", "Clang", "MSVC"]

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/software/debugging/c-cpp-segfault/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-05-17)"

# === RELATED UNITS ===
related_kos:
  related_to:
    - id: "software/debugging/rust-borrow-checker/2026"
      label: "Rust Borrow Checker (memory-safe alternative — segfaults only possible in unsafe blocks)"
    - id: "software/debugging/go-nil-pointer/2026"
      label: "Go nil pointer dereference (managed-language analog — use delve, not GDB)"
    - id: "software/debugging/python-memory-leaks/2026"
      label: "Python Memory Leaks (managed-language memory issues)"
  alternative_to:
    - id: "software/debugging/nodejs-memory-leaks/2026"
      label: "Node.js Memory Leaks (different toolchain — heap profiling, not GDB/Valgrind)"
  often_confused_with:
    - id: "software/debugging/python-recursion-stackoverflow/2026"
      label: "Python recursion stack overflow (Python's stack-limit error vs C/C++ SIGSEGV from deep recursion)"
    - id: "software/debugging/go-nil-pointer/2026"
      label: "Go nil pointer panic (managed-language panic vs unmanaged SIGSEGV — different debugger and recovery model)"

# === CONSTRAINTS & SKIP ===
constraints:
  - "C and C++ only — GDB/Valgrind/ASan workflows in this unit do not apply to Rust, Go, Java, Python, or other managed/memory-safe languages"
  - "Debug symbols required (-g flag) — without them GDB backtraces show only hex addresses and ASan cannot report source file:line locations"
  - "Valgrind and ASan are mutually exclusive — never compile with -fsanitize=address and run under valgrind simultaneously; maintain separate build targets"
  - "ASan requires source recompilation (-fsanitize=address) — you cannot instrument an existing pre-built binary, unlike Valgrind which works on any ELF binary"
  - "Core dump analysis requires the exact binary that produced the dump — a recompiled or stripped binary will give wrong or missing symbol resolution in GDB"
skip_this_unit_if:
  - condition: "Rust panic or crash in unsafe block"
    use_instead: "Rust memory safety guide — Rust's ownership model prevents segfaults except in unsafe blocks, which need Miri or cargo-careful, not GDB/Valgrind"
  - condition: "Go nil pointer dereference or goroutine panic"
    use_instead: "Go nil-pointer / panic debugging — Go has garbage collection and its own panic/recover mechanism; use delve debugger, not GDB"
  - condition: "Java NullPointerException, Python crash, or other managed-language exception"
    use_instead: "Language-specific debugger — managed languages don't produce SIGSEGV (except in native extensions); use JVM/Python profilers and stack traces"
  - condition: "Linux kernel panic, OOPS, or BUG (OS-level crash)"
    use_instead: "Kernel debugging guide — kernel crashes require kgdb, crash utility, or kdump/kexec, not userspace GDB/Valgrind/ASan"

# === SOURCES (8 authoritative sources) ===
sources:
  - id: src1
    title: "Debugging Segmentation Faults and Pointer Problems"
    author: Cprogramming.com
    url: https://www.cprogramming.com/debugging/segfaults.html
    type: community_resource
    published: 2024-01-01
    reliability: high
  - id: src2
    title: "Segmentation Fault in C/C++ — GeeksforGeeks"
    author: GeeksforGeeks
    url: https://www.geeksforgeeks.org/cpp/segmentation-fault-c-cpp/
    type: community_resource
    published: 2024-06-01
    reliability: high
  - id: src3
    title: "AddressSanitizer and Debugger — Google Sanitizers Wiki"
    author: Google
    url: https://github.com/google/sanitizers/wiki/AddressSanitizerAndDebugger
    type: official_docs
    published: 2024-01-01
    reliability: authoritative
  - id: src4
    title: "Valgrind vs AddressSanitizer: Debugging Memory Errors in C/C++"
    author: Undo
    url: https://undo.io/resources/gdb-watchpoint/a-quick-introduction-to-using-valgrind-and-addresssanitizer/
    type: technical_blog
    published: 2024-03-01
    reliability: high
  - id: src5
    title: "Segmentation Fault Debugging Notes — University of Pittsburgh"
    author: Xianei Zhang
    url: https://people.cs.pitt.edu/~xianeizhang/notes/segfault.html
    type: community_resource
    published: 2024-01-01
    reliability: moderate_high
  - id: src6
    title: "How to Use Address Sanitizer — Ohio Supercomputer Center"
    author: Ohio Supercomputer Center
    url: https://www.osc.edu/resources/getting_started/howto/howto_use_address_sanitizer
    type: official_docs
    published: 2024-01-01
    reliability: high
  - id: src7
    title: "Segmentation Fault — Wikipedia"
    author: Wikipedia
    url: https://en.wikipedia.org/wiki/Segmentation_fault
    type: community_resource
    published: 2024-01-01
    reliability: moderate_high
  - id: src8
    title: "GCC 14 Release Series — Changes, New Features, and Fixes"
    author: GNU Project
    url: https://gcc.gnu.org/gcc-14/changes.html
    type: official_docs
    published: 2024-05-07
    reliability: authoritative
---

# How Do I Debug Segmentation Faults in C and C++?

## TL;DR

- **Bottom line**: A segmentation fault (SIGSEGV, signal 11) means your program tried to access memory it does not own. Debug with a 3-tool hierarchy: **GDB** (backtrace the crash site) → **Valgrind Memcheck** (find the root memory error) → **AddressSanitizer** (fastest, catches errors at compile-time instrumentation). ~80% of segfaults are caused by null/dangling pointer dereference, array out-of-bounds access, or use-after-free.
- **Key tool/command**: `gcc -g -fsanitize=address -fno-omit-frame-pointer program.c -o program && ./program`
- **Watch out for**: The segfault crash site is often NOT the root cause — the memory corruption may have happened thousands of instructions earlier. Always use Valgrind or ASan to find the original error.
- **Works with**: GCC >= 4.8, Clang >= 3.1, GDB >= 7.0, Valgrind >= 3.10. All major Linux distros, macOS. Windows uses Access Violation (0xC0000005) instead of SIGSEGV.

## Constraints

- **Always compile with `-g`** before debugging — without debug symbols, GDB and ASan cannot show source file names or line numbers. [src1, src5]
- **Never ignore compiler warnings** — `-Wall -Wextra` catches many patterns that lead to segfaults (uninitialized variables, format string mismatches, implicit function declarations). [src2]
- **Valgrind does not work with ASan** — they are mutually exclusive. Compile with `-fsanitize=address` OR run under `valgrind`, never both simultaneously. [src4]
- **ASan requires recompilation** — unlike Valgrind, you cannot run an existing binary under ASan. You must compile the source with `-fsanitize=address`. [src6]
- **Core dumps must be enabled** — on most systems `ulimit -c` defaults to 0 (no core dumps). Set `ulimit -c unlimited` before running the crashing program to generate a core dump for post-mortem analysis. [src5]
- **Windows uses different tooling** — SIGSEGV is Linux/macOS. On Windows, segfaults manifest as "Access Violation" exceptions. Use Visual Studio debugger or WinDbg instead of GDB/Valgrind. [src7]

## Quick Reference

| # | Cause | Likelihood | Signature | Fix |
|---|---|---|---|---|
| 1 | NULL pointer dereference | ~25% of cases | Crash at address `0x0` or very low address; `si_addr=(nil)` | Check pointer for NULL before dereference; initialize pointers [src2, src7] |
| 2 | Array/buffer out-of-bounds | ~20% of cases | Crash at address near valid heap/stack; Valgrind: "Invalid read/write of size N" | Use bounds checking; replace `char[]` with `std::vector` or `std::string` [src2] |
| 3 | Use-after-free (dangling pointer) | ~15% of cases | Crash at freed heap address; ASan: "heap-use-after-free"; Valgrind: "Invalid read/write" | Set pointer to NULL after `free()`/`delete`; use smart pointers in C++ [src2, src5] |
| 4 | Uninitialized pointer (wild pointer) | ~12% of cases | Crash at random address; `si_addr` is garbage value | Always initialize pointers to `NULL`/`nullptr` [src1, src2] |
| 5 | Stack overflow (deep recursion) | ~10% of cases | Crash near stack boundary; `si_addr` near stack limit; GDB: frame count is huge | Add recursion base case; increase stack size with `ulimit -s`; convert to iteration [src2] |
| 6 | Double free | ~8% of cases | `free(): double free detected`; ASan: "double-free" | Set pointer to NULL after free; use smart pointers [src2, src5] |
| 7 | Writing to read-only memory | ~5% of cases | Crash on string literal address; `char *s = "hello"; s[0] = 'H';` | Use `const char*` for string literals; use `char s[] = "hello"` for mutable strings [src2, src7] |
| 8 | Mismatched alloc/dealloc | ~3% of cases | ASan: "alloc-dealloc-mismatch"; `malloc` freed with `delete` | Match pairs: `malloc`/`free`, `new`/`delete`, `new[]`/`delete[]` [src2] |
| 9 | Format string mismatch | ~2% of cases | `printf("%d", string_ptr)` — crash or garbage output | Use `-Wformat` flag; match format specifiers to argument types [src1] |

## Decision Tree

```
START — Program crashes with "Segmentation fault (core dumped)"
├── Do you have the source code?
│   ├── YES → Recompile with: gcc -g -fsanitize=address -fno-omit-frame-pointer
│   │   ├── ASan prints error report?
│   │   │   ├── YES → Read the report: file:line, access type, alloc/free stack
│   │   │   │   ├── "heap-use-after-free" → Cause #3: dangling pointer
│   │   │   │   ├── "heap-buffer-overflow" → Cause #2: array out-of-bounds
│   │   │   │   ├── "stack-buffer-overflow" → Cause #2: local array overflow
│   │   │   │   ├── "double-free" → Cause #6
│   │   │   │   └── "SEGV on unknown address 0x000000000000" → Cause #1: NULL deref
│   │   │   └── NO → Run under GDB (Step-by-step #2 below)
│   │   └── ASan unavailable (old compiler)?
│   │       └── Use Valgrind: valgrind --tool=memcheck ./program
│   └── NO (binary only) → Use Valgrind or analyze core dump with GDB
│
├── Is there a core dump file?
│   ├── YES → gdb ./program core → bt → frame N → info locals
│   └── NO → Enable: ulimit -c unlimited → reproduce crash → analyze core
│
└── Crash is intermittent / hard to reproduce?
    ├── Run under Valgrind for hours/days (2x slowdown, no recompile)
    ├── Or compile with ASan for always-on detection (2x slowdown)
    └── Check for data races: gcc -fsanitize=thread (for multithreaded code)
```

## Step-by-Step Guide

### 1. Compile with debug symbols and warnings

Always start by recompiling with maximum diagnostics. [src1, src2]

```bash
# C
gcc -g -Wall -Wextra -Werror -O0 program.c -o program

# C++
g++ -g -Wall -Wextra -Werror -O0 -std=c++17 program.cpp -o program
```

**Verify**: `file program` → should show "with debug_info, not stripped"

### 2. Run under GDB to find the crash location

GDB stops at the exact instruction that triggered SIGSEGV. [src1, src5]

```bash
# Start GDB with your program
gdb ./program

# Inside GDB:
(gdb) run                    # Run with no args, or: run arg1 arg2
# ... program crashes ...
# Program received signal SIGSEGV, Segmentation fault.

(gdb) bt                     # Backtrace — shows full call stack
(gdb) bt full                # Backtrace with local variable values
(gdb) frame 0                # Go to the crashing frame
(gdb) info locals            # Show all local variables in this frame
(gdb) print ptr              # Inspect a specific variable
(gdb) print *ptr             # Dereference (will show if NULL)
(gdb) list                   # Show source code around crash point
```

**Verify**: `bt` output → the top frame (frame #0) shows the file and line number of the crash.

### 3. Enable core dumps for post-mortem debugging

If you cannot run interactively under GDB, analyze the crash after the fact. [src5]

```bash
# Enable core dumps (default is often 0 = disabled)
ulimit -c unlimited

# Optional: set core dump location (Linux)
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern

# Run the program — it will crash and create a core file
./program

# Load the core dump in GDB
gdb ./program /tmp/core.program.12345
(gdb) bt            # See where it crashed
(gdb) bt full       # See all variables at crash time
(gdb) frame 3       # Navigate frames
(gdb) info locals   # Inspect variables
```

**Verify**: `ls -la /tmp/core.*` → core file exists and is non-empty.

### 4. Use Valgrind Memcheck to find the root cause

Valgrind finds memory errors that happen BEFORE the crash — the actual root cause. No recompilation needed. [src4, src5]

```bash
# Basic run
valgrind ./program

# Full diagnostics (recommended)
valgrind --tool=memcheck \
         --leak-check=full \
         --show-leak-kinds=all \
         --track-origins=yes \
         --verbose \
         ./program

# Key output to look for:
# "Invalid read of size 4" → reading freed or unallocated memory
# "Invalid write of size 1" → buffer overflow
# "Use of uninitialised value" → uninitialized variable
# "Invalid free()" → double free or wrong allocator
```

**Verify**: Valgrind exit summary shows "ERROR SUMMARY: 0 errors from 0 contexts" when all memory errors are fixed.

### 5. Use AddressSanitizer (fastest, most detailed)

ASan is built into GCC (>= 4.8) and Clang (>= 3.1). ~2x slowdown vs Valgrind's ~20x. [src3, src6]

```bash
# Compile with ASan
gcc -g -fsanitize=address -fno-omit-frame-pointer -O1 program.c -o program

# Run — ASan prints detailed error report on crash
./program

# ASan output includes:
# - Error type (heap-use-after-free, heap-buffer-overflow, etc.)
# - Exact file:line of the bad access
# - Stack trace of the original allocation
# - Stack trace of the deallocation (for use-after-free)
# - Shadow memory dump

# Combine with GDB for interactive debugging
ASAN_OPTIONS=abort_on_error=1 gdb ./program
(gdb) run
# ASan triggers → program aborts → GDB catches it
(gdb) bt
```

**Verify**: Run with `ASAN_OPTIONS=detect_leaks=1` → ASan also reports memory leaks at exit.

### 6. Use UndefinedBehaviorSanitizer for subtle bugs

Many segfaults are caused by undefined behavior that corrupts memory silently. [src6]

```bash
# Compile with both ASan and UBSan
gcc -g -fsanitize=address,undefined -fno-omit-frame-pointer program.c -o program

# UBSan catches:
# - Signed integer overflow
# - Null pointer dereference (before it crashes)
# - Out-of-bounds array indexing
# - Misaligned pointer access
# - Shift by negative or oversized amount
```

**Verify**: `./program` → UBSan prints runtime errors with `file:line:col` precision.

## Code Examples

### C: common segfault patterns and fixes

> Full script: [c-common-segfault-patterns-and-fixes.txt](scripts/c-common-segfault-patterns-and-fixes.txt) (51 lines)

```c
// Input:  None (demonstration of segfault causes)
// Output: Shows 5 common segfault patterns with correct alternatives
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# ... (see full script)
```

### C++: modern segfault prevention with smart pointers

> Full script: [c-modern-segfault-prevention-with-smart-pointers.txt](scripts/c-modern-segfault-prevention-with-smart-pointers.txt) (33 lines)

```cpp
// Input:  None (demonstration of C++ safety patterns)
// Output: Shows smart pointer usage to prevent segfaults
#include <memory>
#include <vector>
#include <string>
# ... (see full script)
```

### Bash: automated segfault debugging workflow

> Full script: [bash-automated-segfault-debugging-workflow.sh](scripts/bash-automated-segfault-debugging-workflow.sh) (32 lines)

```bash
#!/bin/bash
# Input:  Source file path (C or C++)
# Output: Compilation with all sanitizers + GDB + Valgrind diagnostics
SRC="$1"
BIN="${SRC%.c*}.debug"
# ... (see full script)
```

## Anti-Patterns

### Wrong: Dereferencing a pointer without NULL check

```c
// BAD — ptr could be NULL if malloc fails or function returns NULL [src1, src2]
int *ptr = find_record(id);
printf("Value: %d\n", *ptr);  // SEGFAULT if find_record returned NULL
```

### Correct: Always check before dereference

```c
// GOOD — defensive programming prevents crash [src1, src2]
int *ptr = find_record(id);
if (ptr != NULL) {
    printf("Value: %d\n", *ptr);
} else {
    fprintf(stderr, "Record %d not found\n", id);
}
```

### Wrong: Using pointer after free

```c
// BAD — classic use-after-free, may crash or silently corrupt [src2, src5]
char *buf = malloc(256);
snprintf(buf, 256, "data");
free(buf);
printf("Buffer: %s\n", buf);  // SEGFAULT or garbage — buf is dangling
```

### Correct: Null the pointer after free

```c
// GOOD — pointer is safely nulled; any accidental use is caught [src2, src5]
char *buf = malloc(256);
if (buf == NULL) { perror("malloc"); return; }
snprintf(buf, 256, "data");
printf("Buffer: %s\n", buf);  // Use BEFORE free
free(buf);
buf = NULL;  // Prevent dangling pointer reuse
```

### Wrong: Stack-allocated array returned from function

```c
// BAD — returning pointer to local variable; memory is invalid after return [src1]
int* get_data(void) {
    int arr[10] = {1, 2, 3};
    return arr;  // WARNING: returns address of local variable
}
int main(void) {
    int *data = get_data();
    printf("%d\n", data[0]);  // SEGFAULT or garbage — stack frame is gone
}
```

### Correct: Heap-allocate or use caller-provided buffer

```c
// GOOD — heap allocation survives function return [src1]
int* get_data(void) {
    int *arr = malloc(10 * sizeof(int));
    if (arr == NULL) return NULL;
    arr[0] = 1; arr[1] = 2; arr[2] = 3;
    return arr;  // Caller must free()
}
int main(void) {
    int *data = get_data();
    if (data != NULL) {
        printf("%d\n", data[0]);  // Safe — heap memory persists
        free(data);
    }
}
```

### Wrong: Modifying a string literal

```c
// BAD — string literals are in read-only memory [src2, src7]
char *greeting = "hello world";
greeting[0] = 'H';  // SEGFAULT — writing to .rodata section
```

### Correct: Use a char array for mutable strings

```c
// GOOD — array initializer copies literal to mutable stack memory [src2, src7]
char greeting[] = "hello world";  // Creates mutable copy on stack
greeting[0] = 'H';  // Safe — modifying stack memory
```

## Common Pitfalls

- **The crash site is not the root cause**: A buffer overflow at line 50 may corrupt memory that is only accessed at line 500, where the crash occurs. Valgrind or ASan shows the original corruption point, not just the crash. Fix: always run Valgrind/ASan first, not just GDB. [src4, src5]
- **Optimized code hides bugs**: Compiling with `-O2`/`-O3` can reorder or eliminate code, making GDB show wrong line numbers or "optimized out" variables. Fix: debug with `-O0` or at most `-O1 -fno-omit-frame-pointer`. [src1, src6]
- **Valgrind and ASan cannot be combined**: Running a binary compiled with `-fsanitize=address` under Valgrind produces false positives and crashes. Fix: maintain two build targets — one for ASan, one for Valgrind. [src4]
- **Core dumps disabled by default**: Most Linux distros set `ulimit -c 0`. If you run a crashing program without enabling core dumps first, the core file is not generated. Fix: add `ulimit -c unlimited` to your shell profile or Makefile. [src5]
- **Intermittent segfaults from uninitialized variables**: A pointer with garbage value may point to valid memory sometimes and invalid memory other times, making the crash non-reproducible. Fix: compile with `-fsanitize=memory` (MemorySanitizer, Clang only) or use Valgrind `--track-origins=yes`. [src4, src5]
- **`free(ptr)` on stack variable**: Passing a stack-allocated variable address to `free()` corrupts the heap allocator and causes a crash later. Fix: only `free()` what was returned by `malloc()`/`calloc()`/`realloc()`. [src2]
- **Signed integer overflow causing array index corruption**: In C/C++, signed integer overflow is undefined behavior. An overflowed index can become negative, indexing before the array start. Fix: use `-fsanitize=undefined` to catch this. [src6]

## Diagnostic Commands

> Full script: [diagnostic-commands.sh](scripts/diagnostic-commands.sh) (34 lines)

```bash
# === Compile with full debug + sanitizer support ===
# GCC with AddressSanitizer
gcc -g -fsanitize=address -fno-omit-frame-pointer -O1 program.c -o program
# GCC with AddressSanitizer + UndefinedBehaviorSanitizer
gcc -g -fsanitize=address,undefined -fno-omit-frame-pointer program.c -o program
# ... (see full script)
```

## Version History & Compatibility

| Tool | Version | Key Feature | Notes |
|---|---|---|---|
| GDB | >= 7.0 (2009) | Python scripting, reverse debugging | Available on all Linux distros [src1] |
| GDB | >= 13.0 (2023) | Improved C++20 support | Better template debugging |
| Valgrind | >= 3.10 (2014) | Full C++11 support | ~20x slowdown; no recompile needed [src4, src5] |
| Valgrind | >= 3.22 (2023) | macOS Ventura support | Limited ARM support on macOS |
| ASan (GCC) | >= 4.8 (2013) | Basic ASan support | Requires recompilation [src6] |
| ASan (GCC) | >= 12.0 (2022) | Improved container overflow detection | Better C++20 support |
| ASan (GCC) | >= 14.0 (May 2024) | Hardware-assisted ASan (`-fsanitize=hwaddress`) on x86-64 LAM_U57 | Lower overhead than classic ASan; `-mlam=u57` enabled by default [src8] |
| ASan (Clang) | >= 3.1 (2012) | Original ASan implementation | Generally better ASan support than GCC [src3] |
| UBSan (GCC) | >= 4.9 (2014) | Undefined behavior detection | Use with `-fsanitize=undefined` [src6] |
| MSan (Clang) | >= 3.3 (2013) | Uninitialized memory detection | Clang only; not available in GCC |
| TSan (GCC/Clang) | >= 4.8/3.2 | Data race detection | For multithreaded segfaults |

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Program crashes with "Segmentation fault" | Crash message is "Aborted" (SIGABRT) | Check for `assert()` failures or `abort()` calls |
| GDB backtrace shows your code | Crash is inside system library (libc, libpthread) | Check your arguments to library calls |
| Valgrind reports "Invalid read/write" | Valgrind reports "Conditional jump depends on uninitialised value" | Use `-fsanitize=memory` (Clang MSan) for uninitialized reads |
| Need to debug production binary (no source) | Have source code and can recompile | Use ASan — faster and more detailed than Valgrind |
| Intermittent crash in multithreaded code | Single-threaded memory bug | Use ThreadSanitizer: `-fsanitize=thread` |
| macOS or Linux environment | Windows environment | Use Visual Studio debugger or WinDbg |

## Important Caveats

- **ASan ~2x slowdown, Valgrind ~20x slowdown**: ASan is compiled in and runs much faster, but requires recompilation. Valgrind needs no recompilation but is significantly slower — choose based on your workflow. [src4, src6]
- **ASan shadow memory uses ~5x your program's memory**: A program using 1GB of heap will need ~5GB total under ASan. Ensure sufficient RAM. [src6]
- **Valgrind does not support all CPU instructions**: AVX-512 and some newer SIMD instructions may cause Valgrind itself to crash. Compile without `-march=native` when testing under Valgrind. [src4]
- **Segfaults in optimized code may not reproduce in debug builds**: The optimization that triggers the bug (e.g., reordering, vectorization) may not happen at `-O0`. Use `-O1 -fno-omit-frame-pointer` as a compromise for debugging optimized code. [src1, src6]
- **macOS requires code signing for debugging**: On macOS Ventura+, GDB requires codesigning or use of `lldb` (LLVM's debugger, which is the default on macOS) instead. [src4]

## Related Units

- [Rust Borrow Checker](/software/debugging/rust-borrow-checker/2026) — memory-safe alternative; segfaults only possible in unsafe blocks
- [Go nil pointer dereference](/software/debugging/go-nil-pointer/2026) — managed-language analog (use delve, not GDB)
- [Python Memory Leaks](/software/debugging/python-memory-leaks/2026) — managed-language memory issues (no SIGSEGV)
- [Node.js Memory Leaks](/software/debugging/nodejs-memory-leaks/2026) — heap profiling for managed runtimes
