#include <stdio.h>
int main(int argc, char **argv)
{
char c[] = "a";
printf("%d\n", *(int*)(c));
}
Это дает мне SIGBUS после установки set $ps |= (1<<18)
в GDB, которое, по-видимому, выбрасывается, если выравнивание адресов некорректно (среди прочих причин).
РЕДАКТИРОВАТЬ: довольно легко поднять SIGBUS:
int main(int argc, char **argv)
{
/* EDIT: enable AC check */
asm("pushf; "
"orl $(1<<18), (%esp); "
"popf;");
char c[] = "1234567";
char d[] = "12345678";
return 0;
}
Просмотр разборки main в gdb:
Dump of assembler code for function main:
....
0x08048406 <main+34>: mov 0x8048510,%eax
0x0804840b <main+39>: mov 0x8048514,%edx
0x08048411 <main+45>: mov %eax,-0x10(%ebp)
0x08048414 <main+48>: mov %edx,-0xc(%ebp)
0x08048417 <main+51>: movl $0x34333231,-0x19(%ebp) <== BAM! SIGBUS
0x0804841e <main+58>: movl $0x38373635,-0x15(%ebp)
0x08048425 <main+65>: movb $0x0,-0x11(%ebp)
Как бы то ни было, ваша тестовая программа Christoph завершается неудачно в Linux, вызывая SIGBUS, как и должно быть. Это, вероятно, вещь для Windows?
Вы можете включить бит проверки выравнивания в коде, используя этот фрагмент:
/* enable AC check */
asm("pushf; "
"orl $(1<<18), (%esp); "
"popf;");
Также убедитесь, что флаг действительно установлен:
unsigned int flags;
asm("pushf; "
"movl (%%esp), %0; "
"popf; " : "=r"(flags));
fprintf(stderr, "%d\n", flags & (1<<18));