generado error c unix segmentation-fault bus-error

c - generado - bus error linux



¿Qué es un error de autobús? (15)

¿Qué significa el mensaje "error de bus" y en qué se diferencia de un error de seguridad?


Creo que el kernel genera SIGBUS cuando una aplicación muestra una desalineación de datos en el bus de datos. Creo que ya que la mayoría de los compiladores modernos para la mayoría de los procesadores rellenan / alinean los datos para los programadores, los problemas de alineación de antaño (al menos) se mitigan y, por lo tanto, uno no ve SIGBUS con demasiada frecuencia en estos días (AFAIK).

Desde Here


Acabo de descubrir que, en un procesador ARMv7, puede escribir algún código que le dé un fallo de segmentación cuando no esté optimizado, pero le dé un error de bus cuando se compile con -O2 (optimizar más). Estoy usando gcc arm gnueabihf compilador cruzado de ubuntu x64.


Depende de su sistema operativo, CPU, compilador y posiblemente 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 una gran variedad de cosas, dependiendo del entorno y el código que se ejecuta.

-Adán


Estoy de acuerdo con todas las respuestas anteriores. Aquí están mis 2 centavos con respecto al error de BUS:

No es necesario que surja un error de BUS de las instrucciones dentro del código del programa. Esto puede suceder cuando está ejecutando un binario y durante la ejecución, el binario se modifica (se sobrescribe con una compilación o se elimina, etc.).

Verificar si este es el caso: una forma sencilla de verificar si esta es la causa es iniciar instancias en ejecución del mismo binario y ejecutar una compilación. Ambas instancias en ejecución se bloquearían con un error SIGBUS poco después de que la compilación hubiera finalizado y reemplazado el binario (el que está ejecutando actualmente ambas instancias)

Razón subyacente: esto se debe a que el sistema operativo intercambia páginas de memoria y, en algunos casos, el binario completo podría estar en la memoria y estos bloqueos podrían ocurrir cuando el sistema operativo trata de obtener la página siguiente del mismo binario, pero el binario ha cambiado desde la última lectura. eso.


Los errores de bus son raros hoy en día en x86 y ocurren cuando su procesador ni siquiera puede intentar acceder a la memoria solicitada, por lo general:

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

Las fallas de segmentación ocurren cuando se accede a la memoria que no pertenece a su proceso, son muy comunes y generalmente son el resultado de:

  • usando un puntero a algo que fue desasignado.
  • utilizando un puntero no inicializado por lo tanto, falso.
  • utilizando un puntero nulo.
  • desbordando un búfer.

PD: para ser más precisos, esto no es manipular el puntero en sí, lo que causará problemas, es acceder a la memoria a la que apunta (desreferenciación).


Mi razón para el error de bus en Mac OS X fue que traté de asignar aproximadamente 1Mb en la pila. Esto funcionó bien en un subproceso, pero cuando se usa openMP, esto conduce al error de bus, porque Mac OS X tiene un tamaño de pila muy limitado para subprocesos no principales .


Normalmente significa un acceso no alineado.

Un intento de acceder a la memoria que no está físicamente presente también daría un error de bus, pero no verá esto si está utilizando un procesador con una MMU y un sistema operativo que no tiene errores, porque no tendrá ningún error. -Existente memoria asignada al espacio de direcciones de su proceso.


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

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

¿Observa el uso '' inadvertido '' de la variable ''i'' en el primer ''bucle for''? Eso es lo que está causando el error de bus en este caso.


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


También puede obtener SIGBUS cuando una página de códigos no puede paginarse por algún motivo.


Un desbordamiento de búfer típico que resulta 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, se produce un error de bus.


Un ejemplo específico de un error de bus que acabo de encontrar al programar 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 el documento, strcat anexa el segundo argumento al primero cambiando el primer argumento (voltear los argumentos y funciona bien). En linux, esto da un error de segmentación (como se esperaba), pero en OS X da un error de bus. ¿Por qué? Realmente no lo sé.


Un error de seguridad es acceder a la memoria a la que no se le permite acceder. Es de solo lectura, no tienes permiso, etc ...

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


Una instancia clásica de un error de bus se encuentra en ciertas arquitecturas, como el SPARC (al menos algunos SPARC, tal vez esto haya cambiado), es cuando se realiza un acceso mal alineado. Por ejemplo:

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

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


Ejemplo de mmap minimal POSIX 7

El "error de bus" ocurre cuando el kernel envía SIGBUS a un proceso.

Un ejemplo mínimo que lo produce porque se olvidó 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; }

Corre con:

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

Probado en Ubuntu 14.04.

POSIX describes SIGBUS como:

Acceso a una porción indefinida de un objeto de memoria.

La especificación de mmap dice que:

Las referencias dentro del rango de direcciones que comienzan en pa y continúan para bytes de len a páginas completas después del final de un objeto darán como resultado la entrega de una señal SIGBUS.

Y shm_open dice 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.