Pergunta

O que a mensagem média "bus erro", e como é que diferem de um segfault?

Foi útil?

Solução

erros de ônibus são raros hoje em dia em x86 e ocorrem quando o processador não pode nem mesmo tentar o acesso à memória solicitado, tipicamente:

  • usando uma instrução do processador com um endereço que não satisfaz suas necessidades de alinhamento.

falhas de segmentação ocorrer ao acessar memória que não pertence ao seu processo, eles são muito comuns e são normalmente o resultado de:

  • usando um ponteiro para algo que foi desalocado.
  • usando um ponteiro daí falso inicializado.
  • usando um ponteiro nulo.
  • transbordando um buffer.

PS:. Para ser mais preciso isso não está manipulando o ponteiro em si que irá causar problemas, ele está acessando a memória que aponta para (dereferencing)

Outras dicas

A segfault está acessando memória que você não tem permissão para acessar. É somente leitura, você não tem permissão, etc ...

Um erro de bus está tentando memória de acesso que possivelmente não pode estar lá. Você já usou um endereço que é sem sentido para o sistema, ou o tipo errado de endereço para essa operação.

Eu acredito que o kernel aumenta SIGBUS quando uma aplicação exibe dados desalinhamento no barramento de dados. eu acho que que desde que a maioria [?] compiladores modernos para a maioria dos processadores de bloco / o align dados para os programadores, o problemas de alinhamento de outrora (pelo menos) mitigados, e, portanto, não se vê SIGBUS demasiado frequentemente estes dias (AFAIK).

De: Aqui

mmap mínima POSIX 7 exemplo

"erro Bus" acontece quando o kernel envia SIGBUS a um processo.

Um exemplo mínimo que produz porque ftruncate foi esquecido:

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

Executar com:

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

Testado no Ubuntu 14.04.

descreve SIGBUS como:

O acesso a uma parte indefinida de um objeto de memória.

O mmap especificação diz que:

As referências dentro do intervalo de endereços a partir de aa e continuada para len bytes para páginas inteiras após o final de um objeto deve resultar na entrega de um sinal SIGBUS.

E shm_open diz que gera objetos de tamanho 0:

O objeto de memória compartilhada tem um tamanho de zero.

Assim, no *map = 0 estamos tocando após o final do objeto alocado.

memória de pilha Unaligned acessos em ARMv8 aarch64

Isto foi mencionado em: O que é um erro de bus ? para SPARC, mas aqui vou dar um exemplo mais reprodutível.

Tudo que você precisa é um autônomo aarch64 programa:

.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

Esse programa, em seguida, levanta SIGBUS no Ubuntu 18.04 aarch64, kernel Linux 4.15.0 em um ThunderX2 máquina do servidor .

Infelizmente, não posso reproduzi-lo em modo de usuário v4.0.0 QEMU, eu não sei por que.

A culpa parece ser opcional e controlada pelos campos SCTLR_ELx.SA e SCTLR_EL1.SA0, tenho resumiu os documentos relacionados um pouco mais aqui .

Você também pode obter SIGBUS quando uma página de código não pode ser paginada em por algum motivo.

Um exemplo clássico de um erro de bus está em certas arquiteturas, como o SPARC ( pelo menos alguns SPARCs, talvez isso foi alterado), é quando você faz um acesso mis-alinhados. Por exemplo:

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

tentativas esse trecho para escrever o 32-bit valor inteiro 0xdeadf00d para um endereço que é (muito provavelmente) não alinhados corretamente, e irá gerar um erro de bus em arquiteturas que são "exigente" a este respeito. A Intel x86 é, por sinal, não tal arquitetura, permitiria o acesso (embora executá-lo mais lentamente).

Depende de seu sistema operacional, CPU, compilador, e possivelmente outros fatores.

Em geral isso significa que o ônibus CPU não conseguiu completar um comando, ou sofrido um conflito, mas que poderia significar toda uma gama de coisas, dependendo do ambiente e do código que está sendo executado.

-Adam

É normalmente significa um acesso alinhadas-un.

Uma tentativa de memória de acesso que não está fisicamente presente também daria um erro de bus, mas você não vai ver isso se você estiver usando um processador com uma MMU e um sistema operacional que não é de buggy, porque você não vai ter qualquer memória inexistente mapeado para espaço de endereço do seu processo.

Um exemplo específico de um erro de bus Eu só encontrou durante a programação C no OS X:

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

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

No caso de você não se lembra do strcat docs acrescenta o segundo argumento para o primeiro, alterando o primeiro argumento (flip os argumentos e funciona bem). No Linux isso dá uma falha de segmentação (como esperado), mas no OS X dá um erro de bus. Por quê? Eu realmente não sei.

Eu estava ficando um erro de bus quando o diretório raiz estava em 100%.

Minha razão para erro de bus no Mac OS X foi que eu tentei atribuir cerca de 1Mb na pilha. Isso funcionou bem em um fio, mas quando usando OpenMP este unidades para erro ônibus, porque o Mac OS X tem muito limitado tamanho da pilha para tópicos não-principais .

Para adicionar ao que blxtd respondida acima, os erros de ônibus também ocorrer quando o processo de não pode tentar acessar a memória de uma 'variável' em particular .

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

Observe o ' inadvertida ' uso de variável 'i' na primeiro 'loop'? isso é o que está causando o erro de ônibus neste caso.

Eu só descobri da maneira mais difícil que em um processador ARMv7 você pode escrever algum código que lhe dá uma falha de segmentação quando unoptimized, mas dá-lhe um erro de bus quando compilado com -O2 (optimize mais). Eu estou usando gcc braço gnueabihf compilador cruzamento x64 ubuntu.

Eu concordo com todas as respostas acima. Aqui estão meus 2 centavos sobre o erro BUS:

A BUS necessidade de erro não surgem as instruções no código do programa. Isso pode acontecer quando você estiver executando um binário e durante a execução, o binário é modificado (substituído por uma construção ou suprimido etc.).

verificar se este for o caso: Uma maneira simples de verificar se esta é a causa está lançando executando instâncias do mesmo binário e para executar uma compilação. Ambas as instâncias em execução iria falhar com um erro SIGBUS logo após a compilação tem acabado e substituiu o binário (aquele que ambos os casos estão actualmente em execução)

razão subjacente: Isso ocorre porque OS swaps páginas de memória e, em alguns casos toda a força binário estar na memória e essas falhas que ocorrem quando as tentativas do sistema operacional para buscar a próxima página a partir do mesmo binário, mas o binário mudou desde a última lê-lo.

Uma sobrecarga da memória intermédia típica que resulta em erros de autocarro é,

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

Aqui, se o tamanho da string entre aspas ( "") é mais do que o tamanho buf dá erro ônibus.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top