I recently had some problems with unaligned access on IA64, messages about unaligned access were being logged via printk and I couldn’t determine the cause – or even how to track it down. To test what an unaligned access means (which wasn’t documented anywhere that a quick google search could find) I wrote the test program in the second half of this post. Below is the output of the test program which accesses an integer at various offsets. As you can see it’s addresses that are congruent to 5, 6, and 7 mod 8 that cause the errors. At the int is 4 bytes long it seems that the cause of an unaligned access error is an access to a data type that crosses an 8 byte boundary. So a pointer or long long would have to be aligned to an 8 byte boundary, an int has to be at an address that is congruent to 4 or less mod 8, and a character can be anywhere.
Also if the sysctl /proc/sys/kernel/ignore-unaligned-usertrap is set to 1 then these messages will be disabled. But you really don’t want to do that, such errors apparently cause a significant performance loss so you want to file bug reports against programs that do this.
# ./a.out
index: 0
index: 1
a.out(10393): unaligned access to 0x607fffffff34ee25, ip=0x4000000000000961
index: 2
a.out(10393): unaligned access to 0x607fffffff34ee26, ip=0x4000000000000961
index: 3
a.out(10393): unaligned access to 0x607fffffff34ee27, ip=0x4000000000000961
index: 4
index: 5
index: 6
index: 7
index: 8
index: 9
a.out(10393): unaligned access to 0x607fffffff34ee2d, ip=0x4000000000000961
index: 10
a.out(10393): unaligned access to 0x607fffffff34ee2e, ip=0x4000000000000961
index: 11
a.out(10393): unaligned access to 0x607fffffff34ee2f, ip=0x4000000000000961
index: 12
index: 13
Below is the test program I used:
#include <string.h>
#include <stdio.h>
void doit(int *foo)
{
int bar;
memcpy(&bar, foo, sizeof(bar));
if(*foo == 1234)
printf("test\n");
}
int main()
{
char buf[1024];
int i;
for(i=0; i<sizeof(buf); i++)
{
printf("index: %d\n", i);
doit(&buf[i]);
sleep(1);
}
return 0;
}
There is a program called prctl on ia64 that can control what happens to the program. It’s useful to for instance let it generate an signal (SIGBUS?) so you can debug where it happens.
Kurt
Our wiki is often useful for ia64 related things, see
http://www.gelato.unsw.edu.au/IA64wiki/UnalignedAccesses
I don’t understant you program.
Anyway, the processor bus / memory bus should be 128 bit (IIRC, I don’t know AMD64). So the processor can read only 128 bit at time (no more, no less), at a specific alignment. The low part of address identify the chip and is normally hardcoded (for this reasons when vendors increment the bus size, you should use memory bank in parallel).
So if a integer is not aligned, the processor will do two memory calls and in the CPU it will assemble the result (some architecture don’t allow you unaligned data). Since pentium (IIRC), it was possible to cause a CPU exception (for debugging) on non aligned data.
But your code seems wrong: you use memcpy, which is not an atomic operation. memcpy try to resolve access compile-time and run-time in manner to do less CPU loops, but it is not garantee that it will do one single memory access.
And: are you sure that int are 4 byte long on AMD64? I think they are 8 byte long.