如何获得“总线错误”?

发布于 2024-08-18 03:25:31 字数 292 浏览 7 评论 0原文

我正在努力尝试获取总线错误。

一种方法是访问不对齐,我已经尝试了此处给出的示例,并且此处,但没有错误我-程序执行得很好。

是否有某种情况肯定会产生总线错误?

I am trying very hard to get a bus error.

One way is misaligned access and I have tried the examples given here and here, but no error for me - the programs execute just fine.

Is there some situation which is sure to produce a bus error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

笑看君怀她人 2024-08-25 03:25:31

这应该能够在 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 信号的传送。

This should reliably result in a SIGBUS on a POSIX-compliant system.

#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;
}

From the Single Unix Specification, mmap:

References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

并安 2024-08-25 03:25:31

总线错误只能在满足以下条件的硬件平台上调用:

  1. 需要对齐访问,并且
  2. 不通过执行两次对齐访问并组合结果来补偿未对齐访问。

您可能无权访问这样的系统。

Bus errors can only be invoked on hardware platforms that:

  1. Require aligned access, and
  2. Don't compensate for an unaligned access by performing two aligned accesses and combining the results.

You probably do not have access to such a system.

往昔成烟 2024-08-25 03:25:31

尝试以下方法:(

#include <signal.h>
int main(void)
{
    raise(SIGBUS);
    return 0;
}

我知道,可能不是您想要的答案,但几乎肯定会给您带来“总线错误”!)

Try something along the lines of:

#include <signal.h>
int main(void)
{
    raise(SIGBUS);
    return 0;
}

(I know, probably not the answer you want, but it's almost sure to get you a "bus error"!)

┾廆蒐ゝ 2024-08-25 03:25:31

正如其他人提到的,这是非常特定于平台的。在我正在使用的 ARM 系统(没有虚拟内存)上,有很大一部分地址空间没有分配内存或外设。如果我读取或写入这些地址之一,就会出现总线错误。

如果总线上确实存在硬件问题,您也可能会收到总线错误。

如果您在具有虚拟内存的平台上运行,您可能无法故意使程序生成总线错误,除非它是设备驱动程序或其他内核模式软件。无效的内存访问可能会被内存管理器捕获为访问冲突或类似情况(并且它甚至没有机会访问总线)。

As others have mentioned this is very platform specific. On the ARM system I'm working with (which doesn't have virtual memory) there are large portions of the address space which have no memory or peripheral assigned. If I read or write one of those addresses, I get a bus error.

You can also get a bus error if there's actually a hardware problem on the bus.

If you're running on a platform with virtual memory, you might not be able to intentionally generate a bus error with your program unless it's a device driver or other kernel mode software. An invalid memory access would likely be trapped as an access violation or similar by the memory manager (and it never even has a chance to hit the bus).

情仇皆在手 2024-08-25 03:25:31

在具有 Intel CPU 的 Linux 上尝试此操作:

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 的“特殊”寄存器之一中设置“对齐检查”位。

另请参阅:此处

on linux with an Intel CPU try this:

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;
}

the trick here is to set the "alignment check" bit in one of the CPUs "special" registers.

see also: here

软的没边 2024-08-25 03:25:31

我确信您使用的一定是 x86 机器。
X86 cpu 不会产生总线错误,除非其 EFALAGS 寄存器中的 AC 标志被设置。

尝试此代码:

#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

I am sure that you must be using x86 machines.
X86 cpu does not generate bus error unless its AC flag in EFALAGS register is set.

Try this code:

#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;
}

More about this can be found at http://orchistro.tistory.com/206

流绪微梦 2024-08-25 03:25:31

另请记住,某些操作系统会针对访问未对齐以外的错误报告“总线错误”。您在问题中没有提到您实际上想要实现的目标是什么。也许可以这样尝试:

int *x = 0;
*x=1;

您链接到的维基百科页面提到访问不存在的内存也可能导致总线错误。如果将已知无效的地址加载到指针中并取消引用它,您可能会有更好的运气。

Also keep in mind that some operating systems report "bus error" for errors other than misaligned access. You didn't mention in your question what it was you were actually trying to acheive. Maybe try thus:

int *x = 0;
*x=1;

the Wikipedia page you linked to mentions that access to non-existant memory can also result is a bus error. You might have better luck with loading a known-invalid address into a pointer and dereferwncing that.

-残月青衣踏尘吟 2024-08-25 03:25:31

这个怎么样?未经测试。

  #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;
    } 

How about this? untested.

  #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;
    } 
泪眸﹌ 2024-08-25 03:25:31
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(核心已转储)

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';
    }
}

Bus error: 10 (core dumped)

樱花坊 2024-08-25 03:25:31

对于 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 也可能因其他原因而发生。

For 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);
}

Note:If asm instructions are removed, code wont generate the SIGBUS error as suggested by others.
SIGBUS can occur for other reason too.

旧时浪漫 2024-08-25 03:25:31

简单,写入不属于您的内存:

int main()
{
    char *bus_error = 0;

    *bus_error = 'X';
}

在我的 PowerPC Mac [OS X 10.4,双 1ghz PPC7455's] 上出现即时总线错误,不一定是在您的硬件和/或操作系统上。

甚至有一个<一篇关于总线错误的 href="http://en.wikipedia.org/wiki/Bus_error" rel="nofollow noreferrer">wikipedia 文章,包括生成错误的程序。

Simple, write to memory that isn't yours:

int main()
{
    char *bus_error = 0;

    *bus_error = 'X';
}

Instant bus error on my PowerPC Mac [OS X 10.4, dual 1ghz PPC7455's], not necessarily on your hardware and/or operating system.

There's even a wikipedia article about bus errors, including a program to make one.

伊面 2024-08-25 03:25:31

如果您尝试访问计算机无法寻址的内存,则会出现总线错误。例如,计算机内存的地址范围为 0x00 到 0xFF,但您尝试访问 0x0100 或更大的内存元素。

实际上,您的计算机的范围将比 0x00 到 0xFF 大得多。

回答您的原始帖子:

告诉我一些肯定会产生总线错误的情况。

在您的代码中,索引到内存的方式超出了最大内存限制的范围。我不知道...使用某种巨大的十六进制值 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 索引到 char* ...

Bus errors occur if you try to access memory that is not addressable by your computer. For example, your computer's memory has an address range 0x00 to 0xFF but you try to access a memory element at 0x0100 or greater.

In reality, your computer will have a much greater range than 0x00 to 0xFF.

To answer your original post:

Tell me some situation which is sure to produce a bus error.

In your code, index into memory way outside the scope of the max memory limit. I dunno ... use some kind of giant hex value 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF indexed into a char* ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文