What Is a Bus Error (SIGBUS) vs SIGSEGV in C?
Both a bus error (SIGBUS) and a segmentation fault
(SIGSEGV) are fatal signals triggered when a C program
attempts an invalid memory operation, but they stem from fundamentally
different issues within the computer's memory architecture. While a
segmentation fault occurs when a program attempts to access a virtual
memory address that is logically invalid or protected, a bus error
occurs when the hardware physically cannot execute the requested memory
transaction. This guide breaks down the mechanics of
SIGBUS, its primary triggers, and the core differences
separating it from a standard SIGSEGV.
What Is a Bus Error (SIGBUS)?
A bus error, represented by the signal SIGBUS, is raised
by the operating system when the processor attempts to access memory
over the physical data bus and fails due to hardware-level constraints.
Instead of an operating system denying access because of permission
rules, the CPU itself encounters a fault trying to carry out the
physical read or write operation.
In C, a SIGBUS is typically caused by two distinct
scenarios:
1. Unaligned Memory Access
Most processor architectures expect multi-byte data types (like
2-byte short, 4-byte int, or 8-byte
double) to reside at memory addresses that are multiples of
their size. For instance, a 4-byte integer is expected to start at an
address divisible by 4.
While modern x86 architectures often handle unaligned accesses gracefully in hardware at the cost of performance, many RISC architectures (such as SPARC, older ARM variants, and MIPS) strictly forbid it. If code casts a byte pointer to an integer pointer and dereferences an odd address, the CPU raises an alignment fault:
char buffer[10];
// Misaligning an integer pointer to an odd address
int *bad_ptr = (int *)(buffer + 1);
*bad_ptr = 42; // Triggers SIGBUS on architectures requiring strict alignmentSpecialized SIMD instructions on modern x86 processors (such as certain AVX or SSE instructions) can also trigger a bus error if the referenced memory is not aligned to 16, 32, or 64 bytes.
2. Memory-Mapped Files (mmap) Past EOF
The most common cause of SIGBUS on modern systems
involves the mmap() system call. If you map a file into
virtual memory and then attempt to access a portion of the memory that
corresponds to a part of the file that does not exist (for example, if
the file is truncated by another process while mapped), the virtual
address exists, but the physical backing store cannot satisfy the page
fault.
// Mapping a file of size 100 bytes
int fd = open("file.txt", O_RDWR);
char *map = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// If file.txt is only 100 bytes, accessing byte 200 causes SIGBUS
char c = map[200]; What Is a Segmentation Fault (SIGSEGV)?
A segmentation fault, represented by the signal SIGSEGV,
is handled primarily by the CPU's Memory Management Unit (MMU) in
coordination with the OS kernel. It is a logical memory violation rather
than a physical bus error.
A SIGSEGV happens when:
- The address accessed is not mapped to any physical page in virtual
memory (such as dereferencing a
NULLpointer or an uninitialized pointer). - The access violates memory permissions (such as attempting to write data to a read-only code or literal string section).
- A stack overflow exhausts the memory allocated for the call stack.
// Writing to read-only memory triggers SIGSEGV
char *str = "Hello World";
*str = 'h';
// Dereferencing NULL triggers SIGSEGV
int *ptr = NULL;
*ptr = 10;Core Differences: SIGBUS vs. SIGSEGV
| Feature | Bus Error (SIGBUS) |
Segmentation Fault
(SIGSEGV) |
|---|---|---|
| Origin | Hardware bus controller / Physical addressing failure | MMU (Memory Management Unit) / Logical paging fault |
| Root Cause | Alignment violation or non-existent physical backing store | Invalid virtual address or permission violation |
| Common Trigger | Dereferencing unaligned pointers or
truncated mmap regions |
Dereferencing NULL or wild
pointers; writing to read-only memory |
| Platform Behavior | Highly architecture-dependent (strict RISC vs. tolerant CISC) | Consistent across almost all virtual-memory platforms |
Summary
In C programming, the distinction boils down to logical validity versus physical feasibility.
- Use
SIGSEGVto diagnose bugs related to pointer logic: dereferencing unmapped memory, walking off arrays into unmapped boundaries, or violating access permissions. - Use
SIGBUSto diagnose hardware-related constraints: pointer-casting misalignments on strict architectures, or inconsistencies between virtual memory pages and their physical backing storage viammap.