What Is Signal 11? The SIGSEGV Error Explained

Signal 11 is a notification sent by your operating system when a program tries to access memory it isn’t allowed to touch. Its formal name is SIGSEGV (segmentation violation), and when it fires, the offending program crashes immediately with the familiar “Segmentation fault” message. The numeric value 11 is consistent across all major architectures, including x86, ARM, Alpha, SPARC, MIPS, and PARISC.

How Signal 11 Works Under the Hood

Modern processors include a component called the Memory Management Unit (MMU), which sits between your program and physical memory. The MMU maps the virtual addresses your program uses to actual locations in RAM, and it enforces permissions on every memory access. When your program tries to read or write an address it hasn’t been assigned, or tries to write to a read-only region, the MMU flags a fault.

That fault gets handed to the operating system kernel, which identifies the offending process and delivers signal 11 to it. The default behavior is to terminate the process. On Linux, this typically produces the one-line message “Segmentation fault (core dumped)” in your terminal, though the “core dumped” part only appears if core dumps are enabled.

Common Causes in Code

Almost every signal 11 traces back to a bug in how your program handles memory. The most frequent culprits:

  • Dereferencing a NULL or uninitialized pointer. Your pointer doesn’t point to valid memory, so reading or writing through it triggers the fault.
  • Using a dangling pointer. The memory was valid once, but it’s been freed. The pointer still holds the old address, which may now belong to something else or nothing at all.
  • Reading past the end of an array. Accessing index 10 of a 10-element array (which ends at index 9) reads memory your program doesn’t own.
  • Stack overflow. Deep or infinite recursion fills the stack region entirely, and the next function call writes past its boundary.
  • Modifying a string literal. In C, a string like "hello" is stored in read-only memory. Trying to change one of its characters triggers the fault because the MMU blocks writes to that region.
  • Forgetting a null terminator on a C string. String functions keep reading byte by byte until they find a zero. Without one, they run off the end of your buffer into unmapped memory.
  • Mismatched allocation and deallocation. Mixing different memory management functions (for example, allocating with one method and freeing with another) can corrupt internal bookkeeping and cause later accesses to crash.

Languages like C and C++ are especially prone to these bugs because they give you direct control over memory. Higher-level languages like Python or Java handle memory automatically and will throw their own exceptions (like NullPointerException) before things escalate to a signal 11, though native extensions or interpreter bugs can still trigger one.

Signal 11 vs. Bus Error

Signal 11 is sometimes confused with a bus error (SIGBUS, typically signal 10). The distinction matters: signal 11 means your program accessed a valid memory address that it doesn’t have permission to use. A bus error means the address itself is invalid at the hardware level, often because of an alignment problem, like trying to read a 4-byte value from an address that isn’t a multiple of 4. In short, a segfault is a permissions problem, and a bus error is a physical addressing problem.

Debugging a Signal 11 Crash

When your program crashes with “Segmentation fault,” the fastest path to the bug is a debugger like GDB. Run your program inside GDB, reproduce the crash, and it will stop at the exact instruction that triggered the fault. From there, type backtrace to see the full chain of function calls that led to the crash. Use print to inspect pointer values and check whether they’re NULL or pointing somewhere unexpected. The up and down commands let you walk through the call stack to understand how the program arrived at the faulting line.

If you can’t run the program under a debugger (because the crash happens in production, for example), you’ll want a core dump. This is a snapshot of the program’s memory at the moment of the crash, and you can load it into GDB after the fact to get the same backtrace and variable inspection.

Enabling Core Dumps on Linux

Linux disables core dump creation by default. The setting that controls this is a shell resource limit on core file size, which starts at zero (meaning no dump). To enable it for your current session, run:

ulimit -S -c unlimited

To make this permanent for all users, replace the default ulimit -S -c 0 line in /etc/profile with the unlimited version. If you want to restrict core dumps to specific users or groups, configure /etc/security/limits.conf instead. For daemon processes started through init scripts, you may also need to edit /etc/init.d/functions to remove the line that resets the core size limit to zero.

By default, core files are written to the working directory of the crashed process. You can redirect them to a central location and add useful metadata to the filename by writing a pattern to /proc/sys/kernel/core_pattern. For example, /var/crash/core_%e_%p_%h_%t creates files named with the executable name, process ID, hostname, and timestamp.

Handling Signal 11 in Your Program

You can install a custom signal handler that runs when signal 11 is received, instead of letting the program die silently. This is useful for logging a stack trace or writing diagnostic information before the crash. On systems using GCC and glibc, functions like backtrace and backtrace_symbols let you capture and print the call stack from inside the handler.

There’s an important limitation, though: the memory corruption that caused the signal may have also corrupted your program’s state, so the handler itself can’t always be trusted. A signal 11 handler is best treated as a last-resort logging mechanism, not a recovery strategy. The standard practice is to log whatever you can, then let the process terminate. Attempting to “fix” the problem and resume execution from a segfault handler is unreliable and rarely works in practice.