答案 0 :(得分:15)
这应该可靠地在符合POSIX的系统上产生SIGBUS
。
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
int main() {
FILE *f = tmpfile();
int *m = mmap(0, 4, PROT_WRITE, MAP_PRIVATE, fileno(f), 0);
*m = 0;
return 0;
}
来自单一Unix规范,mmap:
从 pa 开始的地址范围内的引用,并且 len 字节继续引用到对象结束后的整个页面将导致传送SIGBUS信号。
答案 1 :(得分:12)
只能在以下硬件平台上调用总线错误:
您可能无法访问此类系统。
答案 2 :(得分:7)
尝试以下方面的内容:
#include <signal.h>
int main(void)
{
raise(SIGBUS);
return 0;
}
(我知道,可能不是你想要的答案,但几乎可以肯定会给你一个“总线错误”!)
答案 3 :(得分:3)
正如其他人所说,这是非常具体的平台。在我正在使用的ARM系统(没有虚拟内存)上,有大部分地址空间没有分配内存或外设。如果我读或写其中一个地址,我会收到总线错误。
如果总线上确实存在硬件问题,也可能会出现总线错误。
如果您在具有虚拟内存的平台上运行,则可能无法故意在程序中生成总线错误,除非它是设备驱动程序或其他内核模式软件。内存管理器可能会将无效的内存访问权限作为访问冲突或类似内容(甚至从未有机会访问总线)。
答案 4 :(得分:3)
试试这个:
int main(int argc, char **argv)
{
# if defined i386
/* enable alignment check (AC) */
asm("pushf; "
"orl $(1<<18), (%esp); "
"popf;");
# endif
char d[] = "12345678"; /* yep! - causes SIGBUS even on Linux-i386 */
return 0;
}
这里的技巧是在其中一个CPU“特殊”寄存器中设置“对齐检查”位。
另见:here
答案 5 :(得分:3)
我确信你必须使用x86机器。 除非设置了EFALAGS寄存器中的AC标志,否则X86 cpu不会产生总线错误。
试试这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *p;
__asm__("pushf\n"
"orl $0x40000, (%rsp)\n"
"popf");
/*
* malloc() always provides aligned memory.
* Do not use stack variable like a[9], depending on the compiler you use,
* a may not be aligned properly.
*/
p = malloc(sizeof(int) + 1);
memset(p, 0, sizeof(int) + 1);
/* making p unaligned */
p++;
printf("%d\n", *(int *)p);
return 0;
}
有关此内容的更多信息,请访问http://orchistro.tistory.com/206
答案 6 :(得分:1)
另请注意,某些操作系统会报告“错误访问”以外的错误的“总线错误”。你没有在你的问题中提到你实际上试图实现的是什么。也许这样试试:
int *x = 0;
*x=1;
您链接的Wikipedia页面提到访问不存在的内存也可能导致总线错误。将一个已知无效的地址加载到指针中并将其解除,可能会更好。
答案 7 :(得分:1)
这个怎么样?未经测试。
#include<stdio.h>
typedef struct
{
int a;
int b;
} busErr;
int main()
{
busErr err;
char * cPtr;
int *iPtr;
cPtr = (char *)&err;
cPtr++;
iPtr = (int *)cPtr;
*iPtr = 10;
}
答案 8 :(得分:1)
int main(int argc, char **argv)
{
char *bus_error = new char[1];
for (int i=0; i<1000000000;i++) {
bus_error += 0xFFFFFFFFFFFFFFF;
*(bus_error + 0xFFFFFFFFFFFFFF) = 'X';
}
}
总线错误:10(核心转储)
答案 9 :(得分:0)
简单,写入不属于你的内存:
int main()
{
char *bus_error = 0;
*bus_error = 'X';
}
我的PowerPC Mac [OS X 10.4,双1ghz PPC7455]上的即时总线错误,不一定在您的硬件和/或操作系统上。
甚至有一个关于总线错误的wikipedia article,包括制作一个错误的程序。
答案 10 :(得分:0)
对于0x86 arch:
#include <stdio.h>
int main()
{
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif
int b = 0;
int a = 0xffffff;
char *c = (char*)&a;
c++;
int *p = (int*)c;
*p = 10; //Bus error as memory accessed by p is not 4 or 8 byte aligned
printf ("%d\n", sizeof(a));
printf ("%x\n", *p);
printf ("%x\n", p);
printf ("%x\n", &a);
}
注意:如果删除了asm指令,代码将不会按其他人的建议生成SIGBUS错误。 SIGBUS也可能出于其他原因。
答案 11 :(得分:-1)
如果您尝试访问计算机无法访问的内存,则会发生总线错误。例如,您的计算机内存的地址范围为0x00到0xFF,但您尝试访问0x0100或更大的内存元素。
实际上,您的计算机将具有比0x00到0xFF更大的范围。
回答原帖:
告诉我一些肯定会产生总线错误的情况。
在您的代码中,索引到超出最大内存限制范围的内存方式。我不知道...使用某种巨型十六进制值0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF索引到一个char * ...