Как получить "ошибку шины"?

Я очень стараюсь получить ошибку шины.

Один из способов - это неправильный доступ, и я попытался привести приведенные примеры здесь и здесь, но для меня нет ошибок - программы выполняются просто отлично.

Есть ли какая-то ситуация, которая обязательно приведет к ошибке шины?

Ответы

Ответ 1

Ошибки шины могут быть вызваны только на аппаратных платформах, которые:

  • Требовать согласованный доступ и
  • Не компенсируйте неравномерный доступ, выполнив два согласованных доступа и объединив результаты.

У вас, вероятно, нет доступа к такой системе.

Ответ 2

Это должно достоверно привести к SIGBUS в POSIX-совместимой системе.

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

Из спецификации Single Unix mmap:

Ссылки в диапазоне адресов, начинающиеся с pa и продолжающиеся для len-байтов на целые страницы, следующие за концом объекта, должны привести к передаче сигнала SIGBUS.

Ответ 3

Попробуйте что-то по строкам:

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

(Я знаю, возможно, не тот ответ, который вы хотите, но он почти наверняка заставит вас "ошибка шины"!)

Ответ 4

Как отмечали другие, это очень специфично для платформы. В ARM-системе, с которой я работаю (у которой нет виртуальной памяти), есть большие части адресного пространства, которые не имеют памяти или периферии. Если я прочитаю или напишу один из этих адресов, я получаю ошибку шины.

Вы также можете получить ошибку шины, если на шине имеется аппаратная проблема.

Если вы работаете на платформе с виртуальной памятью, возможно, вы не сможете преднамеренно генерировать ошибку шины с вашей программой, если это не драйвер устройства или другое программное обеспечение режима ядра. Недопустимый доступ к памяти, скорее всего, будет захвачен как нарушение доступа или подобное с помощью диспетчера памяти (и он никогда не сможет попасть в шину).

Ответ 5

на Linux с процессором Intel попробуйте следующее:

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

трюк здесь заключается в том, чтобы установить бит проверки "выравнивания" в одном из "специальных" регистров ЦП.

см. также: здесь

Ответ 6

Я уверен, что вы должны использовать машины x86. Процессор X86 не генерирует ошибку шины, если не установлен его флаг AC в регистре EFALAGS.

Попробуйте этот код:

#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

Ответ 7

Также имейте в виду, что некоторые операционные системы сообщают "ошибка шины" для ошибок, отличных от несогласованного доступа. Вы не упомянули в своем вопросе, что именно вы на самом деле пытались добиться. Возможно, попробуйте:

int *x = 0;
*x=1;

на странице Википедии, на которую вы ссылались, упоминается, что доступ к несуществующей памяти также может привести к ошибке шины. Возможно, вам повезло с загрузкой известного недействительного адреса в указатель и разделяющее их.

Ответ 8

Как насчет этого? тестировалась.

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

Ответ 9

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 (сброс ядра)

Ответ 10

Простая запись в память, которая не принадлежит вам:

int main()
{
    char *bus_error = 0;

    *bus_error = 'X';
}

Ошибка мгновенной шины на моем PowerPC Mac [OS X 10.4, dual 1ghz PPC7455], не обязательно на вашем оборудовании и/или операционной системе.

Там даже статья wikipedia о ошибках шины, включая программу для ее создания.

Ответ 11

Ошибки шины возникают, если вы пытаетесь получить доступ к памяти, которая не адресуется на вашем компьютере. Например, память вашего компьютера имеет диапазон адресов от 0x00 до 0xFF, но вы пытаетесь получить доступ к элементу памяти в 0x0100 или выше.

В действительности ваш компьютер будет иметь гораздо больший диапазон, чем от 0x00 до 0xFF.

Чтобы ответить на свой оригинальный пост:

Расскажите мне о какой-то ситуации, которая обязательно вызовет ошибку шины.

В вашем коде индексируйте путь к памяти вне пределов максимальной памяти. Я не знаю... использую какое-то гигантское шестнадцатеричное значение 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, проиндексированное в char *...