什么是总线错误?什么是总线错误?(What is a bus error?)

2019-05-09 00:17发布

什么是“总线错误”消息的意思,它是如何从一个段错误有什么不同?

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尺寸更它给总线错误。



文章来源: What is a bus error?