Cómo corregir errores de bus
Error de bus significa error de bus.
Motivo:
Por motivos de rendimiento, la CPU requiere que todos los accesos a datos estén alineados con la dirección. Si se detecta un acceso sin dirección alineada, se envía una señal SIGBUS al proceso, lo que hace que el proceso genere un volcado de núcleo. RISCC, incluido SPARC (una arquitectura de microprocesador), es este tipo de chip. Por ejemplo, los accesos a int deben estar en alineación de 4 bytes, es decir, la dirección debe ser múltiplo de 4, y para alineación de 2 bytes, es decir, la dirección debe ser múltiplo de 2.
Los errores de bus también pueden deberse a problemas físicos de la máquina o al acceso a una dirección física no válida, pero esto es muy raro.
Al ejecutar malloc() en la plataforma Linux, si no hay memoria suficiente, Linux no permitirá que malloc() falle y regrese, pero enviará una señal SIGBUS al proceso actual.
Nota: Si tienes dudas sobre esto, vale la pena probarlo tú mismo para confirmar cómo responde tu sistema actual.
Las diferencias generales entre las señales SIGBUS y SIGSEGV son las siguientes:
1) SIGBUS (error de bus) significa que la dirección correspondiente al puntero es una dirección válida, pero el bus no puede Utilice el puntero correctamente. Generalmente causado por un acceso a datos desalineado.
2) SIGSEGV (fallo de segmentación) significa que la dirección correspondiente al puntero no es válida y no hay memoria física correspondiente a la dirección.
2. Programa de muestra:
1 int main(){
2
3
4
5
6 #si está definido(__GNUC__)
7 # si está definido(__i386__)
8
9 __asm__("pushf/norl $0x40000, (esp)/npopf");
10 # elif definido(__x86_64__)
11
12 __asm__( "pushf/norl $0x40000, (rsp)/npopf");
13 # endif
14 #endif
15
16
17
18
19
20
21
22
23
> 24 matriz corta[16];
25
26 int * p = (int *) amp; 1];
27 *p = 1
28
29 devuelve 1
30 }
El tamaño del tipo corto es de 2 bytes y su dirección debe ser múltiplo de 2. Convierta la dirección de la matriz [1] a int * y acceda a ella, el sistema emitirá una señal SIGBUS, lo que provocará que el programa falle.
Ejemplo de Wiki:
http://en.wikipedia.org/wiki/Bus_error#Bus_error_example
#include lt;stdlib.hgt; p>
int main( int argc, char ** argv) {
int * iptr
char * cptr
#si está definido ( __GNUC__)
# si está definido(__i386__)
__asm__( "pushf/n orl $0x40000, (esp)/n popf" );
# elif definido(__x86_64__)
__asm__( "pushf/n orl $0x40000, (rsp)/n popf" )
# endif
# endif < / p>
cptr = malloc( tamaño de ( int ) 1);
iptr = ( int * ) cptr;
* iptr = 42; devolver 0;
}
$ gcc -ansi sigbus.c -o sigbus
$ ./sigbus
Error de bus
p>$ gdb ./sigbus
(gdb) r
Programa recibió señal SIGBUS, Error de bus.
0x080483ba en main()
p>(gdb) x/i $pc
0x80483ba lt;.main 54gt;: mov DWORD PTR [eax], 0x2a
(gdb) p/x $ eax
$1 = 0x804a009
(gdb) p/t $eax amp (tamaño de(int) - 1)
$2 = 1
III. Dependencias del compilador y de la plataforma de hardware
Como se mencionó anteriormente, para las plataformas x86, los accesos no alineados se permiten de forma predeterminada, pero con un costo de rendimiento. Puede utilizar la macro en el código anterior para activar la función de detección.
Este programa se ejecuta sin problemas si utilizas el compilador Sun Studio. Esto se debe a que el parámetro predeterminado de Sun Studio para la compilación de 32 bits es -xmemalign=8i, donde la configuración de la opción i especifica explícitamente no generar una señal SIGBUS.
Sin embargo, si se compila como un programa de 64 bits, Sun Studio aún encuentra este error cuando usa -xmemalign=8s, donde la configuración de la opción s significa que dichos accesos no alineados generan una señal SIGBUS.
Si insiste en usar GCC en SPARC para compilar este código, puede hacerlo de la siguiente manera:
GCC tiene capacidades de atributos de tipo, por ejemplo, agregar variables posteriores que requieren alineación manual : __attribute__ ((aligned (4))); indica que el desplazamiento especificado es múltiplo de 4.
Por ejemplo:
short array[10] __attribute__ ((aligned (4)));
Sin embargo, este atributo solo es válido para variables visibles para el conector del vinculador, es decir, para variables locales no válidas. Además, esta propiedad es muy granular; por ejemplo, solo funciona en el primer elemento y no establece un desplazamiento para cada miembro de la matriz. Si desea establecer un desplazamiento para una variable local o para cada miembro de una matriz, puede usar el tipo de unión:
union {
short s;
int i ;
}