什么是“总线错误”消息的意思,它是如何从一个段错误有什么不同?
Answer 1:
总线错误是时下难得在x86上,当你的处理器甚至不能尝试内存访问请求,通常会发生:
- 使用具有不满足其对准要求的地址的处理器指令。
分段错误发生访问这不属于你的进程内存的时候,他们是非常普遍,通常的结果是:
- 使用指针的东西,被释放。
- 使用一个未初始化因此伪指针。
- 使用NULL指针。
- 溢出的缓冲区。
PS:为了这不是操纵指针本身会导致一些问题,它的访问它指向(解引用)的记忆更精确。
Answer 2:
段错误的访问,你不能访问内存。 它是只读的,您没有权限,等等。
总线错误是试图去访问内存,不可能在那里。 你用过那是毫无意义的系统,或一种错误的地址为操作的地址。
Answer 3:
我相信内核引发SIGBUS当数据总线上的应用程序展品数据错位。 我认为,由于大多数[?]对于大多数处理器垫现代的编译器/对准了程序员的数据,当年的对齐烦恼(至少)减轻,因此一不看SIGBUS往往这些天(据我所知)。
来自: 这里
Answer 4:
mmap
最小POSIX 7例如
“总线错误”发生时,内核发送SIGBUS
的过程。
产生是因为一个小例子, 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;
}
运行带有:
gcc -std=c99 main.c -lrt
./a.out
经测试在Ubuntu 14.04。
POSIX 描述 SIGBUS
为:
访问存储器对象的一个未定义的部分。
该MMAP规范说:
的地址范围内的引用从pa开始和继续的对象的端部应导致递送SIGBUS信号的以下len个字节到整个页面。
和shm_open
说,它会产生大小为0的对象:
共享存储器对象的尺寸为零点。
因此,在*map = 0
,我们都在触摸过去的分配对象的末尾。
Answer 5:
您还可以得到SIGBUS当一个代码页不能因为某些原因被换英寸
Answer 6:
总线错误的一个典型例子是某些architecures,如SPARC (至少一些SPARCS,也许这已经改变),是当你做一个未对齐的访问。 例如:
unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;
这个片段尝试写入32位整数值0xdeadf00d
到是没有正确对齐的地址(最有可能),并会产生对在这方面是“挑剔”的架构总线错误。 英特尔x86的是,顺便说一下, 没有这样的架构,将允许访问(尽管更慢执行它)。
Answer 7:
这取决于你的操作系统,CPU,编译器,以及其他可能的因素。
一般来说这意味着CPU总线无法完成命令,或者遭受了冲突,但是这可能意味着取决于环境和代码正在运行的事情的整个范围。
-亚当
Answer 8:
它通常是指一个未对齐存取。
试图去访问内存,实际不存在,也将给予总线错误,但你不会看到这一点,如果你使用的是与一个MMU和一个操作系统,这不是马车的处理器,因为你不会有任何非-existent存储器映射到进程的地址空间。
Answer 9:
我只是同时OS X编程C本遇到总线错误的具体例子:
#include <string.h>
#include <stdio.h>
int main(void)
{
char buffer[120];
fgets(buffer, sizeof buffer, stdin);
strcat("foo", buffer);
return 0;
}
如果你不记得了文档strcat
通过改变第一个参数追加的第二个参数的第一个(翻转的参数,它工作正常)。 在Linux上这给分段错误(如预期),但在OS X上,它提供了总线错误。 为什么? 我真的不知道。
Answer 10:
我得到一个总线错误时,根目录是100%。
Answer 11:
我在Mac OS X总线错误的原因是,我试图分配1MB左右的堆栈。 这在一个线程中运行良好,但使用OpenMP时,该驾驶到总线错误,因为Mac OS X中具有非常有限的非主线程的堆栈大小 。
Answer 12:
要添加到什么blxtd上述回答,总线错误时,你的进程不能试图访问特定的“变量”的记忆也发生。
for (j = 0; i < n; j++) {
for (i =0; i < m; i++) {
a[n+1][j] += a[i][j];
}
}
注意变量的“ 无意 ”使用的“i”中的第一个“for循环”? 这就是在这种情况下导致总线错误。
Answer 13:
我刚刚发现了艰辛的道路上的ARMv7的处理器,你可以写一些代码,给你一个分段故障时未优化,但与-O2(优化更多)编译为您提供了一个总线错误。 我使用Ubuntu的,从64 GCC手臂gnueabihf交叉编译器。
Answer 14:
我同意上述所有问题的答案。 这里是我的2关于总线错误仙:
不需要从程序代码中的指令产生总线错误。 这可能发生,当你运行的是二进制和执行过程中,二进制被修改(覆盖由生成或删除等)。
验证如果是这种情况:一个简单的方法来检查,如果是这样的原因,推出相同的二进制的运行情况和运行构建。 无论是正在运行的实例将与崩溃SIGBUS
错误后不久,构建已经完成,并取代了二进制文件(这两个实例当前正在运行的一个)
根本的原因:这是因为OS交换内存页,并在某些情况下,整个二进制可能一个是在内存中,当操作系统尝试到下一个页面从相同的二进制取会发生这些事故,但因为它最后一次读取的二进制文件已经改变它。
Answer 15:
典型的缓冲区溢出,这导致在总线错误是,
{
char buf[255];
sprintf(buf,"%s:%s\n", ifname, message);
}
在这里,如果用双引号(“”)字符串的大小比BUF尺寸更它给总线错误。