문제

"버스 오류"메시지는 무엇을 의미하며, Segfault와 어떻게 다릅니 까?

도움이 되었습니까?

해결책

오늘날 x86에서 버스 오류는 드물며 프로세서가 요청 된 메모리 액세스를 시도 할 수없는 경우에 발생합니다.

  • 정렬 요구 사항을 충족하지 않는 주소로 프로세서 명령어를 사용합니다.

세분화 결함은 프로세스에 속하지 않는 메모리에 액세스 할 때 발생하며, 이는 매우 일반적이며 일반적으로 다음의 결과입니다.

  • 처리 된 무언가에 대한 포인터를 사용합니다.
  • 이기적이지 않은 가짜 포인터를 사용합니다.
  • 널 포인터 사용.
  • 버퍼가 넘치는 것.

추신 : 더 정확하기 위해 이것은 문제를 일으킬 포인터 자체를 조작하는 것이 아니라 (Dereferencing)가 가리키는 메모리에 액세스하는 것입니다.

다른 팁

Segfault는 액세스 할 수없는 메모리에 액세스하고 있습니다. 읽기 전용이고 허가가 없습니다.

버스 오류는있을 수없는 메모리에 액세스하려고합니다. 시스템에 의미가없는 주소 또는 해당 작업에 대한 잘못된 주소를 사용했습니다.

응용 프로그램이 데이터 버스에 데이터 오정렬을 전시 할 때 커널이 SIGBU를 올리라고 생각합니다. 나는 대부분의 프로세서에 대한 대부분의 [?] 최신 컴파일러가 프로그래머에 대한 데이터를 패드 / 정렬하기 때문에, 적어도 (적어도)의 정렬 문제가 완화되었으므로 요즘 SIGBUS가 너무 자주 보이지 않는다고 생각합니다 (AFAIK).

에서: 여기

mmap 최소 POSIX 7 예

"버스 오류"는 커널이 보낼 때 발생합니다 SIGBUS 과정에.

이를 생산하는 최소한의 예 ftruncate 잊혀진 :

#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;
}

실행 :

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

우분투 14.04에서 테스트.

posix 설명합니다 SIGBUS 처럼:

메모리 객체의 정의되지 않은 부분에 대한 액세스.

그만큼 MMAP 사양 그렇게 말합니다 :

PA에서 시작하여 객체 끝에 LEN 바이트를 계속하는 주소 범위 내에서의 참조는 SIGBUS 신호를 전달해야합니다.

그리고 shm_open 그렇게 말합니다 크기 0의 객체를 생성합니다.

공유 메모리 객체의 크기는 0입니다.

그래서 *map = 0 우리는 할당 된 물체의 끝을 지나서 만지고 있습니다.

ARMV8 AARCH64에서 정렬되지 않은 스택 메모리 액세스

이것은 다음에서 언급되었습니다. 버스 오류는 무엇입니까? SPARC의 경우, 그러나 여기서는 더 재현 가능한 예를 제공 할 것입니다.

당신이 필요한 것은 독립형 aarch64 프로그램입니다.

.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

그런 다음이 프로그램은 Ubuntu 18.04 Aarch64, Linux 커널 4.15.0에서 Sigbus를 제기합니다. ThunderX2 서버 시스템.

불행히도 QEMU v4.0.0 사용자 모드에서 재현 할 수는 없습니다. 왜 그런지 잘 모르겠습니다.

결함은 선택 사항이며 SCTLR_ELx.SA 그리고 SCTLR_EL1.SA0 필드, 관련 문서를 요약했습니다 여기에 조금 더.

코드 페이지를 어떤 이유로 페이징 할 수없는 경우 Sigbus를 얻을 수도 있습니다.

버스 오류의 고전적인 인스턴스는 다음과 같은 특정 아키텍처에 있습니다. SPARC (적어도 일부 sparc, 아마도 이것이 바뀌었을 것입니다)는 잘못 정렬 된 액세스를 할 때입니다. 예를 들어:

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

이 스 니펫은 32 비트 정수 값을 쓰려고합니다 0xdeadf00d 제대로 정렬되지 않은 주소로, 이와 관련하여 "까다로운"아키텍처에 버스 오류가 발생합니다. 그건 그렇고, 인텔 x86은 ~ 아니다 이러한 아키텍처는 액세스를 허용합니다 (더 천천히 실행하지만).

OS, CPU, 컴파일러 및 기타 요인에 따라 다릅니다.

일반적으로 CPU 버스가 명령을 완료 할 수 없거나 충돌을 겪을 수는 없지만 환경과 코드가 실행되는 것에 따라 모든 범위의 것들을 의미 할 수 있습니다.

-아담

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.

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.

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

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.

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.

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 gives you a bus error when compiled with -O2 (optimize more). I am using gcc arm gnueabihf cross compiler from ubuntu x64.

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 running instances of the same binary and to run a build. 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 entire binary might one be in memory and these crashes would occur when the OS tries to fetch the next page from the same binary, but the binary has changed since it last read it.

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top