"总线错误"消息的含义是什么,它与段错误有什么不同?
现在,在x86上很少出现总线错误,并且当您的处理器甚至无法尝试请求的内存访问时发生错误,通常是:
使用处理器指令,其地址不满足其对齐要求.
访问不属于您的进程的内存时会发生分段错误,它们非常常见,通常是以下结果:
使用指向已解除分配的内容的指针.
使用未初始化的虚假指针.
使用空指针.
溢出缓冲区.
PS:更确切地说,这不是操纵会导致问题的指针本身,而是访问它指向的内存(解除引用).
段错误是访问您不允许访问的内存.这是只读的,你没有权限等等......
总线错误正在尝试访问不可能存在的内存.您使用了对系统无意义的地址,或者该操作的错误地址类型.
我相信当应用程序在数据总线上出现数据错位时,内核会引发SIGBUS.我认为,由于大多数处理器的大多数[?]现代编译器为程序员填充/对齐数据,因此过去(至少)减少了对齐问题,因此现在人们看不到SIGBUS(AFAIK).
来自:这里
mmap
最小的POSIX 7示例
内核发送SIGBUS
到进程时发生"总线错误" .
产生它的最小例子因为ftruncate
被遗忘了:
#include/* O_ constants */ #include /* ftruncate */ #include /* 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开始并且在对象结束之后继续len字节到整个页面的地址范围内的引用将导致SIGBUS信号的传递.
并shm_open
说它生成大小为0的对象:
共享内存对象的大小为零.
所以*map = 0
我们正在触及分配对象的末尾.
当代码页由于某种原因无法被分页时,您也可以获得SIGBUS.