What is a bus error? Is it different from a segmentation fault?

CUnixSegmentation FaultBus Error

C Problem Overview


What does the "bus error" message mean, and how does it differ from a segmentation fault?

C Solutions


Solution 1 - C

Bus errors are rare nowadays on x86 and occur when your processor cannot even attempt the memory access requested, typically:

  • using a processor instruction with an address that does not satisfy its alignment requirements.

Segmentation faults occur when accessing memory which does not belong to your process. They are very common and are typically the result of:

  • using a pointer to something that was deallocated.
  • using an uninitialized hence bogus pointer.
  • using a null pointer.
  • overflowing a buffer.

PS: To be more precise, it is not manipulating the pointer itself that will cause issues. It's accessing the memory it points to (dereferencing).

Solution 2 - C

A segfault is accessing memory that you're not allowed to access. It's read-only, you don't have permission, etc...

A bus error is trying to access memory that can't possibly be there. You've used an address that's meaningless to the system, or the wrong kind of address for that operation.

Solution 3 - C

mmap minimal POSIX 7 example

"Bus error" happens when the kernel sends SIGBUS to a process.

A minimal example that produces it because ftruncate was forgotten:

#include <fcntl.h> /* O_ constants */
#include <unistd.h> /* ftruncate */
#include <sys/mman.h> /* mmap */

int main() {
    int fd;
    int *map;
    int size = sizeof(int);
    char *name = "/a";

    shm_unlink(name);
    fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600);
    /* THIS is the cause of the problem. */
    /*ftruncate(fd, size);*/
    map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    /* This is what generates the SIGBUS. */
    *map = 0;
}

Run with:

gcc -std=c99 main.c -lrt
./a.out

Tested in Ubuntu 14.04.

POSIX describes SIGBUS as:

> Access to an undefined portion of a memory object.

The mmap spec says that:

> References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

And shm_open says that it generates objects of size 0:

> The shared memory object has a size of zero.

So at *map = 0 we are touching past the end of the allocated object.

Unaligned stack memory accesses in ARMv8 aarch64

This was mentioned at: https://stackoverflow.com/questions/212466/what-is-a-bus-error/212519#212519 for SPARC, but here I will provide a more reproducible example.

All you need is a freestanding aarch64 program:

.global _start
_start:
asm_main_after_prologue:
    /* misalign the stack out of 16-bit boundary */
    add sp, sp, #-4
    /* access the stack */
    ldr w0, [sp]

    /* exit syscall in case SIGBUS does not happen */
    mov x0, 0
    mov x8, 93
    svc 0

That program then raises SIGBUS on Ubuntu 18.04 aarch64, Linux kernel 4.15.0 in a ThunderX2 server machine.

Unfortunately, I can't reproduce it on QEMU v4.0.0 user mode, I'm not sure why.

The fault appears to be optional and controlled by the SCTLR_ELx.SA and SCTLR_EL1.SA0 fields, I have summarized the related docs a bit further here.

Solution 4 - C

> I believe the kernel raises SIGBUS > when an application exhibits data > misalignment on the data bus. I think > that since most[?] modern compilers > for most processors pad / align the > data for the programmers, the > alignment troubles of yore (at least) > mitigated, and hence one does not see > SIGBUS too often these days (AFAIK).

From: Here

Solution 5 - C

On POSIX systems, you can also get the SIGBUS signal when a code page cannot be paged in for some reason.

Solution 6 - C

I agree with all the answers above. Here are my 2 cents regarding the BUS error:

A BUS error need not arise from the instructions within the program's code. This can happen when you are running a binary and during the execution, the binary is modified (overwritten by a build or deleted, etc.).

Verifying if this is the case

A simple way to check if this is the cause is by launching a couple of instances of the same binary form a build output directory, and running a build after they start. Both the running instances would crash with a SIGBUS error shortly after the build has finished and replaced the binary (the one that both the instances are currently running).

Underlying Reason

This is because OS swaps memory pages and in some cases, the binary might not be entirely loaded in memory. These crashes would occur when the OS tries to fetch the next page from the same binary, but the binary has changed since the last time it was read.

Solution 7 - C

One classic instance of a bus error is on certain architectures, such as the SPARC (at least some SPARCs, maybe this has been changed), is when you do a misaligned access. For instance:

unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;

This snippet tries to write the 32-bit integer value 0xdeadf00d to an address that is (most likely) not properly aligned, and will generate a bus error on architectures that are "picky" in this regard. The Intel x86 is, by the way, not such an architecture. It would allow the access (albeit execute it more slowly).

Solution 8 - C

A specific example of a bus error I just encountered while programming C on OS X:

#include <string.h>
#include <stdio.h>

int main(void)
{
    char buffer[120];
    fgets(buffer, sizeof buffer, stdin);
    strcat("foo", buffer);
    return 0;
}

In case you don't remember the docs strcat appends the second argument to the first by changing the first argument(flip the arguments and it works fine). On linux this gives a segmentation fault(as expected), but on OS X it gives a bus error. Why? I really don't know.

Solution 9 - C

I was getting a bus error when the root directory was at 100%.

Solution 10 - C

It depends on your OS, CPU, compiler, and possibly other factors.

In general, it means the CPU bus could not complete a command, or suffered a conflict, but that could mean a whole range of things, depending on the environment and code being run.

Solution 11 - C

It normally means an un-aligned access.

An attempt to access memory that isn't physically present would also give a bus error, but you won't see this if you're using a processor with an MMU and an OS that's not buggy, because you won't have any non-existent memory mapped to your process's address space.

Solution 12 - C

My reason for bus error on Mac OS X was that I tried to allocate about 1Mb on the stack. This worked well in one thread, but when using openMP this drives to bus error, because Mac OS X has very limited stack size for non-main threads.

Solution 13 - C

Firstly SIGBUS and SIGSEGV are not a specific type of error but are groups or families of errors. This is why you typically see a signal number(si_no) and a signal code(si_code).

They also depend on the os and architecture as to what can cause them exactly.

Generally we can say that. A SIGSEGV is related to memory mappings(permissions,no mapping) i.e. an mmu error.

A SIGBUS is when the memory mapping succeeds and you hit an issue with the underlying memory system(out of memory, No memory at that location, alignment, smmu prevents access, etc..), i.e. a bus error..

A SIGBUS can also be with mmapped files, if the file vanishes from the system e.g. you mmap a file on a removable media and it gets unplugged.

A good place to look on a platform is the siginfo.h header, to get an idea of the signal sub types. e.g. for linux This page provides an overview. https://elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/siginfo.h#L245

/*
 * SIGSEGV si_codes
 */
#define SEGV_MAPERR	1	/* address not mapped to object */
#define SEGV_ACCERR	2	/* invalid permissions for mapped object */
#define SEGV_BNDERR	3	/* failed address bound checks */
#ifdef __ia64__
# define __SEGV_PSTKOVF	4	/* paragraph stack overflow */
#else
# define SEGV_PKUERR	4	/* failed protection key checks */
#endif
#define SEGV_ACCADI	5	/* ADI not enabled for mapped object */
#define SEGV_ADIDERR	6	/* Disrupting MCD error */
#define SEGV_ADIPERR	7	/* Precise MCD exception */
#define SEGV_MTEAERR	8	/* Asynchronous ARM MTE error */
#define SEGV_MTESERR	9	/* Synchronous ARM MTE exception */
#define NSIGSEGV	9

/*
 * SIGBUS si_codes
 */
#define BUS_ADRALN	1	/* invalid address alignment */
#define BUS_ADRERR	2	/* non-existent physical address */
#define BUS_OBJERR	3	/* object specific hardware error */
/* hardware memory error consumed on a machine check: action required */
#define BUS_MCEERR_AR	4
/* hardware memory error detected in process but not consumed: action optional*/
#define BUS_MCEERR_AO	5
#define NSIGBUS		5

a Final note is that, all signals can also be user generated e.g. kill. If it is user generated then the si_code is SI_USER. So special sources get negative si_codes.

/*
 * si_code values
 * Digital reserves positive values for kernel-generated signals.
 */
#define SI_USER		0		/* sent by kill, sigsend, raise */
#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
#define SI_QUEUE	-1		/* sent by sigqueue */
#define SI_TIMER	-2		/* sent by timer expiration */
#define SI_MESGQ	-3		/* sent by real time mesq state change */
#define SI_ASYNCIO	-4		/* sent by AIO completion */
#define SI_SIGIO	-5		/* sent by queued SIGIO */
#define SI_TKILL	-6		/* sent by tkill system call */
#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
#define SI_ASYNCNL	-60		/* sent by glibc async name lookup completion */

#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)

Solution 14 - C

I just found out the hard way that on an ARMv7 processor you can write some code that gives you a segmentation fault when unoptimized, but it gives you a bus error when compiled with -O2 (optimize more).

I am using the GCC ARM gnueabihf cross compiler from Ubuntu 64 bit.

Solution 15 - C

For me, I accidentally triggered a "Bus Error" by not declaring that my assembly was heading back into the .text section. It might seem obvious but it had me stumped for a while.

Eg.

.globl _myGlobal # Allocate a 64-bit global with the value 2
.data
.align 3
_myGlobal:
.quad 2
.globl _main # Main function code
_main:
push %rbp

Was missing a text directive when returning to code from data:

_myGlobal:
.quad 2
.text # <- This
.globl _main
_main:

Hope this ends up helpful to someone

Solution 16 - C

One notable cause is that SIGBUS is returned if you attempt to mmap a region of /dev/mem which userspace isn't allowed to access.

Solution 17 - C

A typical buffer overflow which results in Bus error is,

{
    char buf[255];
    sprintf(buf,"%s:%s\n", ifname, message);
}

Here if size of the string in double quotes ("") is more than buf size it gives bus error.

Solution 18 - C

To add to what blxtd answered above, bus errors also occur when your process cannot attempt to access the memory of a particular 'variable'.

for (j = 0; i < n; j++) {
    for (i =0; i < m; i++) {
        a[n+1][j] += a[i][j];
    }
}

Notice the 'inadvertent' usage of variable 'i' in the first 'for loop'? That's what is causing the bus error in this case.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionraldiView Question on Stackoverflow
Solution 1 - CbltxdView Answer on Stackoverflow
Solution 2 - CClinton PierceView Answer on Stackoverflow
Solution 3 - CCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 4 - COliView Answer on Stackoverflow
Solution 5 - CJoshuaView Answer on Stackoverflow
Solution 6 - CAditya Vikas DevarapalliView Answer on Stackoverflow
Solution 7 - CunwindView Answer on Stackoverflow
Solution 8 - CErik VesteraasView Answer on Stackoverflow
Solution 9 - CgoCardsView Answer on Stackoverflow
Solution 10 - CAdam DavisView Answer on Stackoverflow
Solution 11 - CMark BakerView Answer on Stackoverflow
Solution 12 - CAlleoView Answer on Stackoverflow
Solution 13 - CJohn KearneyView Answer on Stackoverflow
Solution 14 - CoromoiluigView Answer on Stackoverflow
Solution 15 - CdeeBoView Answer on Stackoverflow
Solution 16 - CdavolfmanView Answer on Stackoverflow
Solution 17 - CVinaya SagarView Answer on Stackoverflow
Solution 18 - CstuxnettingView Answer on Stackoverflow