Can someone provide an example were casting a pointer from one type to another fails due to mis-alignment?
In the comments to this answer, bothie states that doing s
#include
int main(int argc, char **argv)
{
char c[] = "a";
printf("%d\n", *(int*)(c));
}
This gives me a SIGBUS after setting set $ps |= (1<<18) in gdb, which apparently is thrown when address alignment is incorrect (amongst other reasons).
EDIT: It's fairly easy to raise 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;
}
Looking at main's disassembly in gdb:
Dump of assembler code for function main:
....
0x08048406 : mov 0x8048510,%eax
0x0804840b : mov 0x8048514,%edx
0x08048411 : mov %eax,-0x10(%ebp)
0x08048414 : mov %edx,-0xc(%ebp)
0x08048417 : movl $0x34333231,-0x19(%ebp) <== BAM! SIGBUS
0x0804841e : movl $0x38373635,-0x15(%ebp)
0x08048425 : movb $0x0,-0x11(%ebp)
Anyhow, Christoph your test program fails under Linux raising a SIGBUS as it should. It's probably a Windows thing?
You can enable the Alignment Check bit in code using this snippet:
/* enable AC check */
asm("pushf; "
"orl $(1<<18), (%esp); "
"popf;");
Also, ensure that the flag was indeed set:
unsigned int flags;
asm("pushf; "
"movl (%%esp), %0; "
"popf; " : "=r"(flags));
fprintf(stderr, "%d\n", flags & (1<<18));