Как получить "ошибку шины"?
Я очень стараюсь получить ошибку шины.
Один из способов - это неправильный доступ, и я попытался привести приведенные примеры здесь и здесь, но для меня нет ошибок - программы выполняются просто отлично.
Есть ли какая-то ситуация, которая обязательно приведет к ошибке шины?
Ответы
Ответ 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 *...