如何解决bus error

如题所述

一,Bus Error究竟是指什么

Bus Error,即总线错误。

引发原因:

CPU处于性能方面的考虑,要求对数据进行访问时都必须是地址对齐的。如果发现进行的不是地址对齐的访问,就会发送SIGBUS信号给进程,使进程产生 core dump。RISC包括SPARC(一种微处理器架构)都是这种类型的芯片。x86系列CPU都支持不对齐访问,也提供了开关禁用这个机制。x86架构不要求对齐访问的时候,必定会有性能代价。例如,对int的访问应该是4字节对齐的,即地址应该是4的倍数,对short则是2字节对齐的,地址应该是2的倍数。

Bus Error也有可能是因为机器物理问题或者访问无效物理地址,但这种情况非常少见。

Linux平台上执行malloc(),如果没有足够的RAM,Linux不是让malloc()失败返回,而是向当前进程分发SIGBUS信号。
注: 对该点执怀疑态度,有机会可自行测试确认当前系统反应。

SIGBUS与SIGSEGV信号的一般区别如下:

1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。

2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。

二,例子程序:

1 int main(){
2
3
4
5
6 #if defined(__GNUC__)
7 # if defined(__i386__)
8
9 __asm__("pushf/norl $0x40000,(%esp)/npopf");
10 # elif defined(__x86_64__)
11
12 __asm__("pushf/norl $0x40000,(%rsp)/npopf");
13 # endif
14 #endif
15
16
17
18
19
20
21
22
23
24 short array[16];
25
26 int * p = (int *) &array[1];
27 *p = 1;
28
29 return 1;
30 }

short类型大小为2个字节,其地址必是2的倍数。而对于int指针来说,能够使用以访问数据的地址应该是4的倍数,转化arrary[1]的地址为int *并访问,系统会发出SIGBUS信号,导致程序崩溃。

wiki上的例子:

http://en.wikipedia.org/wiki/Bus_error#Bus_error_example
#include <stdlib.h>

int main( int argc, char ** argv) {
int * iptr;
char * cptr;

#if defined(__GNUC__)
# if defined(__i386__)

__asm__( "pushf/n orl $0x40000,(%esp)/n popf" ) ;
# elif defined(__x86_64__)

__asm__( "pushf/n orl $0x40000,(%rsp)/n popf" ) ;
# endif
#endif

cptr = malloc( sizeof ( int ) + 1) ;

iptr = ( int * ) ++ cptr;

* iptr = 42 ;

return 0 ;
}
$ gcc -ansi sigbus.c -o sigbus
$ ./sigbus
Bus error
$ gdb ./sigbus
(gdb) r
Program received signal SIGBUS , Bus error.
0x080483ba in main ()
(gdb) x/i $pc
0x80483ba <main+54>: mov DWORD PTR [eax],0x2a
(gdb) p/x $eax
$1 = 0x804a009
(gdb) p/t $eax & (sizeof(int) - 1)
$2 = 1

三,编译器和硬件平台相关性

上述已经描述,对于x86平台,默认允许非对齐访问,只不过会有性能代价。开启检测可以使用上述代码中的宏。

这段程序如果用Sun Studio编译器的话,运行就没有问题。这是因为Sun Studio默认对32位编译使用的参数是-xmemalign=8i,其中i选项设置明确指明不产生SIGBUS信号。
不过如果编译成64位程序,Sun Studio使用的-xmemalign=8s,其中s选项设置意味对这种非对齐访问产生SIGBUS信号,则仍旧会遇到这个错误。

如果坚持在SPARC上使用GCC去编译这种代码,可以如下进行:
GCC有一个Type Attributes特性,例如在需人工对齐的变量后加上:__attribute__ ((aligned (4))); 其意义就是指定偏移量为4的倍数。比如:
short array[10] __attribute__ ((aligned (4)));

不过这个属性只对Linker连接器可见的变量有效,也就是说对local variable无效。而且这种特性作用粒度比较大,比如这里只对第一个元素有作用,并不为数组的每个成员设置偏移量。如果一定要针对local variable或者数组的每个成员进行偏移量设置,可以使用union类型:
union {
short s;
int i;
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2015-09-29
bus error总线错误;

在x86+Linux上写的程序,在PC机上运行得很好。可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行的时候,
出现了Bus error。
出现的位置如下(其中Debug的内容是我在程序中添加的调试信息):
root@211.69.193.189:~# arm_v5t_le-gcc -g shit.c
root@211.69.193.189:~# ./a.out
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52
Bus error
打开调试器进行调试:
root@211.69.193.189:~# gdb a.out
GNU gdb 6.3 (MontaVista 6.3-20.0.22.0501131 2005-07-22)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "armv5tl-montavista-linuxeabi"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) run // 运行程序
Starting program: /home/zpf/a.out
Debug: in get_program_info()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send LIN_RST
Debug: in my_sendn()
Debug: send 4 bytes to server:
Debug: gonna receive LIN_RSP
Debug: in my_recvn()
Debug: nleft = 3
Debug: received first 3 bytes from server: 7
Debug: gonna check if 3rd byte is the package type
Debug: received package length = 55
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52

Program received signal SIGBUS, Bus error. // 在这里出现了错误
0x00009624 in alloc_prog_mem (detail_buf=0x13118 "\001\002",
err_buf_ptr=0xbefffc40 "") at shit.c:631
631 g_data_ptr->progtype_num = *(short *)ptr ;//这个是第631行源代码,出错的代码
(gdb) print ptr // 查看一下ptr的值
$1 = 0x13119 "\002" // 地址起始是奇数!!!
(gdb) set ptr=0x1311a // 想改一下
(gdb) continue
Continuing.

Program terminated with signal SIGBUS, Bus error.
The program no longer exists. // 可惜程序已经退出
(gdb) quit

其中,g_data_ptr->progtype_num是一个short类型的值。
把强制类型转换改为用memcpy()写值之后,再调试
root@211.69.193.189:~# gdb test
GNU gdb 6.3 (MontaVista 6.3-20.0.22.0501131 2005-07-22)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "armv5tl-montavista-linuxeabi"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) break 626 // 把刚刚的那句强制类型转换变成内存拷贝
Breakpoint 1 at 0x9630: file test.c, line 626.
(gdb) run
Starting program: /home/zpf/test
Debug: in get_program_info()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send LIN_RST
Debug: in my_sendn()
Debug: send 4 bytes to server:
Debug: gonna receive LIN_RSP
Debug: in my_recvn()
Debug: nleft = 3
Debug: received first 3 bytes from server: 7
Debug: gonna check if 3rd byte is the package type
Debug: received package length = 55
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52

Breakpoint 1, alloc_prog_mem (detail_buf=0x13118 "\001\002",
err_buf_ptr=0xbefffc40 "") at test.c:626
warning: Source file is more recent than executable.

626 memcpy(&(g_data_ptr->prog_num), ptr, 2) ; // 在这一句中断,就是把上面那句出错的源代码改成memcpy
(gdb) print ptr // 再看看ptr
$1 = 0x1311b "\003" // 还是奇数地址
(gdb) continue // 继续执行
Continuing.
Debug: sum_progtype = 2 , sum_prog = 3
Debug: gonna malloc space for progtype_ptr
Debug: gonna malloc space for prog_ptr
Debug: in mv_pkg2prog_list()
Debug: gonna set ProgramType program_type_name
Debug: ProgramType program_type_name set OK
Debug: in $ == *ptr, j = 0
Debug: g_data_ptr->progtype_ptr[j].prog_ptr = temp_prog_ptr
Debug: in @ == *ptr, ptr = 0x13126
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
Debug: in @ == *ptr, ptr = 0x1312f
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
Debug: gonna set ProgramType program_type_name
Debug: ProgramType program_type_name set OK
Debug: in $ == *ptr, j = 1
Debug: g_data_ptr->progtype_ptr[j].prog_ptr = temp_prog_ptr
Debug: in @ == *ptr, ptr = 0x13142
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
program type[0]
program_type_id = 1
program_type_name = love
program_num = 2
prog_ptr = 0x131d8
program[0]
program_id = 1001
program_name = you
format = 1
program[1]
program_id = 1002
program_name = me
format = 2
program type[1]
program_type_id = 2
program_type_name = hatred
program_num = 1
prog_ptr = 0x13248
program[0]
program_id = 2005
program_name = kill
format = 5
Debug: gonna return an OK
Debug: Entering send_exit_requstion()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send EXIT_RST
Debug: in my_sendn()
Debug: send 4 bytes to server:
Debug: in my_recvn()
Debug: nleft = 4
Debug: gonna return an OK

Program exited normally. // 执行通过了!!!!
(gdb)

总结:
问题总算找到了,就是我企图在一个奇数地址起始的地方强制类型转换得到一个short值。
在Intel系列处理器上,可以在任一奇数内存地址储存任何变量或数组,不会导致任何致命的错误影响,只是效率可能会降低。
但在DaVinci上,这一点 不行。所以必须对大于一个字节的数据类型小心谨慎,比较安全的方法是使用
内存拷贝函数memcpy(),或者使用下面的代替方法:
// 先定义一个联合体
union {
short short_val ;
char short_byte[2] ;
} myshort ;
// 然后,把程序中本来应该是
// g_data_ptr->progtype_num = *(short *)ptr ;
// ptr += 2 ;
// 这两句的地方换成下面五句:
myshort.short_byte[0] = *ptr ;
ptr++ ;
myshort.short_byte[1] = *ptr ;
ptr++ ;
g_data_ptr->progtype_num = myshort.short_val ;
// 当然,最简单的方法是换成下面两句:
// memcpy(&(g_data_ptr->progtype_num), ptr, 2) ;
// ptr += 2 ;

对于这个问题的进一步探讨:
在DaVinci上应该注意内存编址模式的问题。
struct {
char struc_char ;
int struc_int ;
short struc_short ;
long struct_long ;
} struc_val ;
在宽松模式下,尽管struc_char只有1个字节,struc_short占2个字节,但编译器可能给这两个变量分别分配了4个字节,
结果整个结构的 大小变成了16个字节,而在编译器设为紧凑模式时,则正好是11个字节。根据计算机数据总线的位数,
不同的编址模式存取数据的速度不一样。我认为在符合总 线字长的情况下,效率是最高的,因为只需进行一次总线操作。
内存编址模式会影响字节对齐方式,字节对齐操作可以解决以下两个主要的问题:
1.访存效率问题;一般的编译器要对内存进行对齐,在处理变量时,编译器会根据一定的设置将长短不同的变量的数据
长度进行对齐以加快内存处理速度。
2.强制类型转换问题:在x86上,字节不对齐的操作只会影响效率,但是在DaVinci上,可能就是一个Bus error,
因为它要求必须字节对齐。
字节对齐的准则
1.数据类型自身的对齐值:对于char型数据,其自身对齐值为1,对于short型为2,对于int,long,float,double类型,
其自身对齐值为4字节。
2.结构体的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
对于平时定义变量,尽可能先定义长度为4的倍数的变量,然后是长度是2的变量,最后是长度为1的变量。

通过测试,GCC编译器是按照4字节对齐存放于内存的。而我还没有发现更改编址模式的参数。程序如下:
#include

int main()
{
struct {
char struc_char ;
int struc_int ;
short struc_short ;
long struct_long ;
} struc_val ;
char c_char ;
int i_int ;
short s_short ;
long l_long ;

printf("sizeof(struc_val) = %d\n", sizeof(struc_val));
printf("sizeof(c_char) = %d\n", sizeof(c_char));
printf("sizeof(i_int) = %d\n", sizeof(i_int));
printf("sizeof(s_short) = %d\n", sizeof(s_short));
printf("sizeof(l_long) = %d\n", sizeof(l_long));

printf("address of struc_val = %p\n", &struc_val);
printf("address of struc_char = %p\n", &(struc_val.struc_char));
printf("address of struc_int = %p\n", &(struc_val.struc_int));
printf("address of struc_short = %p\n", &(struc_val.struc_short));
printf("address of struct_long = %p\n", &(struc_val.struct_long));
printf("address of c_char = %p\n", &c_char);
printf("address of i_int = %p\n", &i_int);
printf("address of s_short = %p\n", &s_short);
printf("address of l_long = %p\n", &l_long);

return 0 ;
}
测试结果:
sizeof(struc_val) = 16
sizeof(c_char) = 1
sizeof(i_int) = 4
sizeof(s_short) = 2
sizeof(l_long) = 4
address of struc_val = 0xbf885278
address of struc_char = 0xbf885278
address of struc_int = 0xbf88527c
address of struc_short = 0xbf885280
address of struct_long = 0xbf885284
address of c_char = 0xbf885277
address of i_int = 0xbf885270
address of s_short = 0xbf88526e
address of l_long = 0xbf885268

所以对于一个32位的数据来讲,如果其没有在4字节整除的内存地址处存放,那么处理器就需要2个总线周期对其进行访问。

0x08 | byte8 | byte9 | byteA | byteB |
0x04 | byte4 | byte5 | byte6 | byte7 |
0x00 | byte0 | byte1 | byte2 | byte3 |
对 于我刚刚的那个出现Bus error的程序,假设指针ptr刚好是指向了byte3(地址是0x0),然后想进行short强制类型转换,
使用byte3,byte4来构成一个 short类型的值,由于第一次总线的数据只有byte0,byte1,byte2,byte3,取不到byte4,
这在DaVinci板子上,就是一个 Bus error了,因为没有达到边界对齐。如果ptr指的是byte2(地址0x02),就没有问题了。
因为0x02地址值是sizeof(short)的整 数倍。

最近在论坛上看到一个程序员在询问Bus Error的问题。他有一个非常简单的测试程序,将一个short数组中第二个成员变量的地址附给一个int型的指针,接着给该指针赋值,大致代码如下:
short array[10];
int * p = (int *) &array[1];
*p = 1;
运行的平台是Solaris for SPARC,使用的编译器是GCC,程序执行到指针赋值的时候的出现Bus Error出错信息,程序coredump。他觉得非常奇怪,代码在X86平台运行的很好。其实这个问题完全是由于CPU硬件不同所造成的。
Bus Error通常都是因为非对齐访问造成的。CPU在设计上为了性能上的考虑,要求待访问,操作的数据地址都要对齐。如果发现没有对齐的访问,就会向当前进程发出SIGBUS信号,使程序崩溃。RISC包括SPARC都是这种类型的芯片。而X86架构就没有这种对齐要求。所以这段代码在Solaris 10 for X86下面没有问题,当然这是有性能的代价。Bus Error也有可能是因为机器物理问题或者访问无效物理地址,但这种情况非常少见。
上面的代码正是这种非对齐访问造成的Bus Error。short是两个字节,其地址偏移量必是2的倍数。而对于int指针来说,需要偏移量地址是4的倍数的数据,所以直接用int指针来操作地址,就很有可能导致系统发出SIGBUS信号,程序崩溃。
这段程序如果用Sun Studio编译器的话,运行就没有问题。这是因为Sun Studio默认对32位编译使用的参数是-xmemalign=8i,其中i选项设置明确不会产生这种SIGBUS信号。不过如果编译成64位程序,Sun Studio使用的-xmemalign=8s,其中s选项设置意味对这种非对齐访问产生SIGBUS信号,仍旧会遇到这个错误。
当然你也可以坚持在SPARC上使用GCC去编译这种代码。GCC有一个Type Attributes特性,在需人工对齐的变量后加上:__attribute__ ((aligned (4))); 4就是指定偏移量。比如:
short array[10] __attribute__ ((aligned (4)));
不过这个属性只对Linker连接器可见的变量有效,也就是说对local variable无效。而且这种特性只能照顾到该数组,即第一个元素,并不为数组的每个成员设置偏移量。
如果一定要针对local variable或者数组的每个成员进行偏移量设置,可以考虑定义一个union的类型:
union {
short s;
int i;
}
第2个回答  2018-07-28
最近在论坛上看到一个程序员在询问Bus Error的问题。他有一个非常简单的测试程序,将一个short数组中第二个成员变量的地址附给一个int型的指针,接着给该指针赋值,大致代码如下:
short array[10];
int * p = (int *) &array[1];*p = 1;
运行的平台是Solaris for SPARC,使用的编译器是GCC,程序执行到指针赋值的时候的出现Bus Error出错信息,程序coredump。他觉得非常奇怪,代码在X86平台运行的很好。其实这个问题完全是由于CPU硬件不同所造成的。
Bus Error通常都是因为非对齐访问造成的。CPU在设计上为了性能上的考虑,要求待访问,操作的数据地址都要对齐。如果发现没有对齐的访问,就会向当前进程发出SIGBUS信号,使程序崩溃。RISC包括SPARC都是这种类型的芯片。而X86架构就没有这种对齐要求。所以这段代码在Solaris 10 for X86下面没有问题,当然这是有性能的代价。Bus Error也有可能是因为机器物理问题或者访问无效物理地址,但这种情况非常少见。
上面的代码正是这种非对齐访问造成的Bus Error。short是两个字节,其地址偏移量必是2的倍数。而对于int指针来说,需要偏移量地址是4的倍数的数据,所以直接用int指针来操作地址,就很有可能导致系统发出SIGBUS信号,程序崩溃。
这段程序如果用Sun Studio编译器的话,运行就没有问题。这是因为Sun Studio默认对32位编译使用的参数是-xmemalign=8i,其中i选项设置明确不会产生这种SIGBUS信号。不过如果编译成64位程序,Sun Studio使用的-xmemalign=8s,其中s选项设置意味对这种非对齐访问产生SIGBUS信号,仍旧会遇到这个错误。
当然你也可以坚持在SPARC上使用GCC去编译这种代码。GCC有一个Type Attributes特性,在需人工对齐的变量后加上:__attribute__ ((aligned (4))); 4就是指定偏移量。比如:
short array[10] __attribute__ ((aligned (4)));
不过这个属性只对Linker连接器可见的变量有效,也就是说对local variable无效。而且这种特性只能照顾到该数组,即第一个元素,并不为数组的每个成员设置偏移量。
如果一定要针对local variable或者数组的每个成员进行偏移量设置,可以考虑定义一个union的类型:union {short s;int i;}
第3个回答  2015-10-28
bus error 是总线错误,这个错误一般是程序无法有效兼容当前 CPU 的工作而报错。
在x86+Linux上写的程序,在PC机上运行得很好。可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行的时候,出现了Bus error。
出现的位置如下(其中Debug的内容是我在程序中添加的调试信息):
root@211.69.193.189:~# arm_v5t_le-gcc -g shit.c
root@211.69.193.189:~# ./a.out
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52
Bus error
打开调试器进行调试:
root@211.69.193.189:~# gdb a.out
GNU gdb 6.3 (MontaVista 6.3-20.0.22.0501131 2005-07-22)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "armv5tl-montavista-linuxeabi"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) run // 运行程序
Starting program: /home/zpf/a.out
Debug: in get_program_info()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send LIN_RST
Debug: in my_sendn()
Debug: send 4 bytes to server: 
Debug: gonna receive LIN_RSP
Debug: in my_recvn()
Debug: nleft = 3
Debug: received first 3 bytes from server: 7
Debug: gonna check if 3rd byte is the package type
Debug: received package length = 55
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52

Program received signal SIGBUS, Bus error. // 在这里出现了错误
0x00009624 in alloc_prog_mem (detail_buf=0x13118 "\001\002",
err_buf_ptr=0xbefffc40 "") at shit.c:631
631 g_data_ptr->progtype_num = *(short *)ptr ;
(gdb) print ptr // 查看一下ptr的值
$1 = 0x13119 "\002" // 地址起始是奇数!!!
(gdb) set ptr=0x1311a // 想改一下
(gdb) continue
Continuing.

Program terminated with signal SIGBUS, Bus error.
The program no longer exists. // 可惜程序已经退出
(gdb) quit

其中,g_data_ptr->progtype_num是一个short类型的值。
把强制类型转换改为用memcpy()写值之后,再调试
root@211.69.193.189:~# gdb test
GNU gdb 6.3 (MontaVista 6.3-20.0.22.0501131 2005-07-22)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "armv5tl-montavista-linuxeabi"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) break 626 // 把刚刚的那句强制类型转换变成内存拷贝
Breakpoint 1 at 0x9630: file test.c, line 626.
(gdb) run
Starting program: /home/zpf/test
Debug: in get_program_info()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send LIN_RST
Debug: in my_sendn()
Debug: send 4 bytes to server: 
Debug: gonna receive LIN_RSP
Debug: in my_recvn()
Debug: nleft = 3
Debug: received first 3 bytes from server: 7
Debug: gonna check if 3rd byte is the package type
Debug: received package length = 55
Debug: malloc space for the actual data: temp_buf = 0x13118
Debug: in my_recvn()
Debug: nleft = 52

Breakpoint 1, alloc_prog_mem (detail_buf=0x13118 "\001\002",
err_buf_ptr=0xbefffc40 "") at test.c:626
warning: Source file is more recent than executable.

626 memcpy(&(g_data_ptr->prog_num), ptr, 2) ; // 在这一句中断
(gdb) print ptr // 再看看ptr
$1 = 0x1311b "\003" // 还是奇数地址
(gdb) continue // 继续执行
Continuing.
Debug: sum_progtype = 2 , sum_prog = 3
Debug: gonna malloc space for progtype_ptr
Debug: gonna malloc space for prog_ptr
Debug: in mv_pkg2prog_list()
Debug: gonna set ProgramType program_type_name
Debug: ProgramType program_type_name set OK
Debug: in $ == *ptr, j = 0
Debug: g_data_ptr->progtype_ptr[j].prog_ptr = temp_prog_ptr
Debug: in @ == *ptr, ptr = 0x13126
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
Debug: in @ == *ptr, ptr = 0x1312f
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
Debug: gonna set ProgramType program_type_name
Debug: ProgramType program_type_name set OK
Debug: in $ == *ptr, j = 1
Debug: g_data_ptr->progtype_ptr[j].prog_ptr = temp_prog_ptr
Debug: in @ == *ptr, ptr = 0x13142
Debug: temp_prog_ptr->format = *ptr
Debug: temp_prog_ptr->program_id = *(int *)ptr
Debug: gonna set Program program_name
Debug: Program program_name set OK
Debug: finished one loop of while
program type[0]
program_type_id = 1
program_type_name = love
program_num = 2
prog_ptr = 0x131d8
program[0]
program_id = 1001
program_name = you
format = 1
program[1]
program_id = 1002
program_name = me
format = 2
program type[1]
program_type_id = 2
program_type_name = hatred
program_num = 1
prog_ptr = 0x13248
program[0]
program_id = 2005
program_name = kill
format = 5
Debug: gonna return an OK
Debug: Entering send_exit_requstion()
Debug: in conn_server(char *err_buf_ptr)
Debug: gonna create a socket
Debug: gonna fill in the serv_addr structure
Debug: gonna connect to a server
Debug: gonna send EXIT_RST
Debug: in my_sendn()
Debug: send 4 bytes to server: 
Debug: in my_recvn()
Debug: nleft = 4
Debug: gonna return an OK

Program exited normally. // 执行通过了!!!!
(gdb)
第4个回答  推荐于2016-03-02
har * p = (char*)malloc(sizeof(int)+1);
p++;
printf("%d\n", *(int*)p);
在新机器上运行是没有问题的。
只有
预先调用
__asm__("pushf\n"
"orl $0x40000, (%rsp)\n"
"popf");
把EFLAGS的AC打开才会报bus error本回答被提问者和网友采纳

Windows蓝屏DATA_BUS_ERROR修复教程_电脑出现蓝屏0x0000002E怎么修复...
解决硬件问题:如果硬件最近已添加到系统,请将其删除以查看错误是否再次发生。如果现有硬件出现故障,请卸下或更换故障部件。应运行系统制造商提供的硬件诊断,以确定哪个硬件组件出现故障。有关这些过程的详细信息,请参阅计算机的用户手册。检查计算机中的所有适配器卡是否已正确就位。使用电子电源商店提供的...

如何解决bus error
Bus Error,即总线错误。引发原因:CPU处于性能方面的考虑,要求对数据进行访问时都必须是地址对齐的。如果发现进行的不是地址对齐的访问,就会发送SIGBUS信号给进程,使进程产生 core dump。RISC包括SPARC(一种微处理器架构)都是这种类型的芯片。x86系列CPU都支持不对齐访问,也提供了开关禁用这个机制。x86...

Bus error是什么?
bus error 是总线错误,这个错误一般是程序无法有效兼容当前 CPU 的工作而报错。在x86+Linux上写的程序,在PC机上运行得很好。可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行的时候,出现了Bus error。出现的位置如下(其中Debug的内容是我在程序中添加的调试信息):root@211.69.193.189:~#...

如何解决bus error
在Intel系列处理器上,可以在任一奇数内存地址储存任何变量或数组,不会导致任何致命的错误影响,只是效率可能会降低。但在DaVinci上,这一点不行。所以必须对大于一个字节的数据类型小心谨慎,比较安全的方法是使用内存拷贝函数memcpy(),或者使用下面的代替方法:\/\/ 先定义一个联合体 union { short shor...

c语言bus error无法解决,高分求救命!!在线等,12:00以前需要交_百度知 ...
UNIX系统没用过,看到这样用(别追问):include <stdio.h> include <unistd.h> FILE* fp = fopen("test.dat", "w+");fwrite(buffer, size, 1, fp);int fd = ::fileno(fp); \/\/获取文件描述符 ::fsync(fd); \/\/强制写硬盘

雨林木风Win7旗舰版系统经常出现非法操作的解决方法
一、系统内存奇偶校验出错,错误码编号为:0x0000002E说明文字ATA-BUS-ERROR解决方法:1)将所有新近安装的硬件卸载掉。2)运行由计算机制造商提供的系统诊断软件,尤其是硬件诊断软件。3)禁用BIOS内存选项。4)确保硬件设备驱动程序和系统BIOS都是最新版本。5)使用硬件供应商提供的系统诊断,运行内存检查来...

Linux环境是用vim命令读取文件的时候,提示bus error,哪位高手知道怎么解...
你可以先试一下vi管不管,首先文件应该没问题,你测试一下,先touch 123这个文件试试,然后再用Vim 123看看能不能进行编辑,如果这样还不行那就是vim的原因了,可以上网下载Vim如果是红帽的Linux或者centos就用yum install vim,如果是Ubuntu就用apt-get install vim安装一下就可以了 ...

bus fatal error on bus 0怎么处理
从提示错误信息看估计是PCI-E总线设备故障。建议拔插下PCI接口上的部件试试,如果仍有问题,这种情况,建议去较正规的戴尔中国大陆地区维修服务网点去检修看看,不是专业人员的误操作是有可能损坏电脑的

simulink中BUS error的问题
你是不是使用的别人的模型在自己的软件上,如果版本不一样可能会这样,你把模型复制下在自己的版本下新建一个粘贴上应该就好了。如果用到了GUI记得也改成和自己版本配套的,不知道能不能解决你的问题,成功的话请采纳哦~

万能的大神们啊,为什么是bus error ?C语言
你的C语言程序我帮你改完了,出现bus error的原因是循环变量b,你使用了unsigned int类型,改成int类型,就没问题了.另外,reverse_bits函数没有返回值,应该定义为void reverse_bits(unsigned int value);完整的C语言程序如下 include<stdio.h>void reverse_bits(unsigned int value);int main(){ unsigned...

相似回答