2008-10-17 7 views
203

¿Qué significa el mensaje "error de bus" y cómo difiere de una segfault?¿Qué es un error de autobús?

+2

Me gustaría agregar una explicación simple para ambos: La falla de segmentación significa que está tratando de acceder a la memoria que no tiene permiso (por ejemplo, no es parte de su programa). Sin embargo, en un error de bus, generalmente significa que está intentando acceder a la memoria que no existe (por ejemplo, intenta acceder a una dirección en 12G pero solo tiene memoria 8G) o si excede el límite de memoria utilizable. – xdevs23

Respuesta

189

Los errores de bus son raros hoy en día en x86 y se producen cuando el procesador no puede ni siquiera intentar el acceso a la memoria solicitada, por lo general:

  • utilizando una instrucción de procesador con una dirección que no satisface sus requisitos de alineación.

fallos de segmentación se producen cuando se accede a la memoria que no pertenece a su proceso, que son muy comunes y suelen ser el resultado de:

  • usando un puntero a algo que se cancela la asignación.
  • utilizando un puntero falso no inicializado.
  • usando un puntero nulo.
  • desbordamiento de un búfer.

PD: Para ser más precisos, esto no está manipulando el puntero en sí mismo, lo que provocará problemas, es acceder a la memoria que señala (desreferencia).

+71

No son raros; Estoy en el Ejercicio 9 de Cómo aprender C a la manera difícil y ya encontré uno ... – 11684

+11

Otra causa de errores de bus (en Linux de todos modos) es cuando el sistema operativo no puede respaldar una página virtual con memoria física (p. Ej. condiciones de poca memoria o de grandes páginas cuando se usa una enorme memoria de página.) Por lo general, mmap (y malloc) solo reservan el espacio de direcciones virtuales, y el kernel asigna la memoria física bajo demanda (llamadas fallas de página blandas). malloc, y luego escribe lo suficiente y obtendrás un error de bus. – Eloff

+0

para mí la partición que contiene '/ var/cache' simplemente estaba llena https://askubuntu.com/a/915520/493379 – c33s

2

Depende de su sistema operativo, CPU, compilador y posiblemente de otros factores.

En general, significa que el bus de la CPU no pudo completar un comando, o sufrió un conflicto, pero eso podría significar todo un rango de cosas dependiendo del entorno y el código que se está ejecutando.

-Adam

9

creo que el núcleo plantea SIGBUS cuando una aplicación de datos exhibe desalineación en el bus de datos. Creo que, dado que la mayoría [?] Compiladores modernos para la mayoría de los procesadores de la almohadilla/alinear los datos para los programadores, los problemas de alineación de antaño (al menos) mitigado, y por lo tanto no se ve SIGBUS con demasiada frecuencia en estos días (HASTA DONDE SE).

Desde: Here

+0

Depende de los trucos desagradables que está haciendo con su código. Puede desencadenar un error de BUS/Trampa de alineación si hace algo tonto como Hacer matemáticas de puntero y luego encasilla para acceder a un modo de problema (es decir, configura una matriz uint8_t, agrega una, dos o tres al puntero de la matriz y luego la encasilla a corto, int, o largo e intenta acceder al resultado ofensivo.) Los sistemas X86 prácticamente te permitirán hacer esto, aunque a una penalización de rendimiento real. * ALGUNOS * sistemas ARMv7 te permitirán hacer esto, pero la mayoría de ARM, MIPS, Power, etc. te lo agradecerán. – Svartalf

68

una violación de segmento es tener acceso a la memoria que no está permitido el acceso. Es de solo lectura, no tiene permiso, etc.

Un error de bus está intentando acceder a la memoria que no puede estar allí. Usó una dirección que no tiene sentido para el sistema o el tipo de dirección incorrecto para esa operación.

2

Normalmente significa un acceso no alineado.

Un intento de acceso a la memoria que no está físicamente presente también generará un error de bus, pero no lo verá si está usando un procesador con una MMU y un sistema operativo que no tiene errores, porque no ganó t tiene una memoria inexistente asignada al espacio de direcciones de su proceso.

+2

Mi i7 ciertamente tiene una MMU, pero aún encontré este error mientras aprendía C en OS X (pasando el puntero no inicializado a 'scanf'). ¿Eso significa que OS X Mavericks tiene fallas? ¿Cuál hubiera sido el comportamiento en un sistema operativo sin errores? –

3

Una instancia clásica de un error de bus es en ciertos arquitectros, como el SPARC (al menos algunos SPARC, tal vez esto se ha cambiado), es cuando se realiza un mal alineamiento de acceso. Por ejemplo:

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

Este fragmento intenta escribir el valor entero de 32 bits 0xdeadf00d a una dirección que es (lo más probable) no está correctamente alineado, y generará un error de bus en arquitecturas que son "delicado" en este considerar. El Intel x86 es, por cierto, no tal arquitectura, permitiría el acceso (aunque lo ejecute más lentamente).

+1

En el caso, tenía datos [8]; Esto ahora es un múltiplo de 4 en una arquitectura de 32 bits. Por lo tanto, está alineado. ¿Recibiré el error ahora? Además, explique: ¿es una mala idea para una conversión de tipo de datos para los punteros? ¿Causará errores de desalineación en una arquitectura frágil? Por favor, elabora, me ayudará. –

+0

Heh. No se trata tanto de la conversión de tipo como de la conversión de tipo en un puntero en el que haya hecho las operaciones matemáticas de puntero. Mire * cuidadosamente * en el código de arriba. El compilador ha alineado cuidadosamente su puntero para datos, y luego lo arruina todo en el compilador al desplazar la referencia por DOS y encasillar a un acceso muy alineado para lo que va a ser un límite no dword. – Svartalf

+0

"Frágil" no es la palabra que usaría para todo esto.Las máquinas y el código X86 han hecho que la gente haga cosas bastante tontas durante un tiempo, siendo esta una de ellas. Repensa tu código si tienes este tipo de problema; para empezar, no es muy efectivo en X86. – Svartalf

5

También puede obtener SIGBUS cuando una página de códigos no puede ser localizada por alguna razón.

+4

Esto sucede a menudo cuando actualizo el archivo .so mientras ejecuto el proceso – poordeveloper

+0

Otra razón para suceder es si intentas 'mmap' un archivo más grande que el tamaño de'/dev/shm' – ilija139

-1

un desbordamiento del búfer típica que se traduce en un error de bus es,

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

Aquí, si el tamaño de la cadena entre comillas dobles ("") es más que el tamaño buf da error en el bus.

+1

Heh ... si este fuera el caso, tendrías problemas de error BUS en lugar de los exploits que destruyen la pila sobre los cuales leíste todo el tiempo Windows y otras máquinas. Los errores de BUS son causados ​​por un intento de acceso a "memoria" que la máquina simplemente no puede acceder porque la dirección no es válida. (De ahí el término "BUS" error.) Esto puede deberse a una serie de fallas, incluidas alineaciones no válidas, y similares, siempre que el procesador no pueda colocar la dirección en las líneas de bus. – Svartalf

0

Para agregar a lo que blxtd respondió anteriormente, los errores de bus también ocurren cuando su proceso no puede intentar acceder a la memoria de una 'variable' en particular.

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

Nota la utilización 'inadvertida' de variable 'i' en el primera 'bucle'? Eso es lo que está causando el error de bus en este caso.

2

Un ejemplo específico de un error de bus acabo encontrado durante la programación C en OS X:

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

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

En caso de que no recuerde la documentación anexa strcat el segundo argumento de la primera cambiando el primer argumento (Da la vuelta a los argumentos y funciona bien). En Linux esto produce un error de segmentación (como se esperaba), pero en OS X da un error de bus. ¿Por qué? Realmente no lo sé

+0

Probablemente la protección de desbordamiento de la pila aumenta el error de bus. – Joshua

+1

'" foo "' se almacena en un segmento de solo lectura de la memoria, por lo que es imposible escribir en él. No sería protección de desbordamiento de pila, solo protección de escritura de memoria (esto es un agujero de seguridad si su programa puede reescribirse). –

0

Me acabo de enterar de la manera difícil que en un procesador ARMv7 puede escribir un código que le da un error de segmentación cuando no se optimiza, pero le da un error de bus cuando se compila con -O2 (optimice más). Estoy usando gcc arm gnueabihf cross compiler de ubuntu x64.

3

mmap POSIX mínimo 7 ejemplo

"error Bus" ocurre cuando el núcleo envía SIGBUS a un proceso.

Un ejemplo mínima que produce porque ftruncate fue olvidado:

#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 con:

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

probado en Ubuntu 14.04.

POSIX describesSIGBUS como:

acceso a una parte indefinida de un objeto de memoria.

El mmap spec dice que:

referencias dentro del rango de direcciones a partir de las pa y continuando durante bytes LEN a páginas enteras a partir del final de un objeto dará lugar a la entrega de una señal de SIGBUS.

Y shm_opensays that que genera objetos de tamaño 0:

El objeto de memoria compartida tiene un tamaño de cero.

Así que en *map = 0 estamos tocando más allá del final del objeto asignado.

1

Mi razón de error de bus en Mac OS X fue que traté de asignar aproximadamente 1Mb en la pila. Esto funcionó bien en un hilo, pero cuando se usa openMP esto conduce al error de bus, porque Mac OS X tiene muy limitado stack size for non-main threads.

-2

Esto también podría referirse a problemas humanos. En varios campos de investigación (quizás más amplio), el "error de autobús" de jerga tiene un significado diferente, que creo que podría ser una respuesta relevante. Cuando solo hay una persona que sabe cómo hacer algo crucial para un flujo de trabajo particular, y esa persona no está disponible de repente (es decir,, "cae debajo de un autobús", pero lo más probable es que sube y baja inesperadamente), esto se conoce como un error de bus Es tan catastrófico como un error de autobús "real", ya que sin el conocimiento de esta persona sobre cómo mantener o incluso ejecutar el flujo de trabajo de investigación, todo el sistema se desmorona. Ser vulnerable a los errores de autobús es un signo de mala gestión.

2

Recibí un error de bus cuando el directorio raíz estaba al 100%.