您的位置:首页 > 其它

How-To Find the Source of "Unaligned Access"

2010-11-18 15:04 513 查看
 

 

How-To Find the Source of "Unaligned Access"

The memory bus on a computer varies in width based on the memory
architeture of the computer. A 32-bit computer has a bus that is
wide enough for 32 bits to be read from the bus at once. A
64-bit computer has a bus wide enough for 64 bits. The computer
wants values to be stored in memory to make the most efficient
use of the memory bus, which means that it should require the
smallest number of read operations to pull a value (or series of
values) off of the bus.

To satisfy this goal, an int should be aligned along a 4-byte
boundary, so that one can be read from the bus with one read on a
32-bit system or two can be read from the bus on a 64-bit
system. Shorts should be aligned along 2-byte boundaries. Chars
can show up anywhere. And pointers should be aligned along the
boundary indicated by the width of the memory bus (a 4-byte
boundary for a 32-bit system and 8-byte for a 64-bit system).

The compiler will structure your program in memory as necessary
to ensure that variables are properly aligned. However, a
programming error can still result in a variable becoming
misaligned. The two most common causes of this are using invalid
pointer values (e.g. dereferencing an uninitialized pointer) and
casting a pointer into a pointer of a larger type (e.g. casting
a char pointer into an int pointer).

Here is some code that intentionally casts pointers in order to
generate unaligned access errors:

#include

int main ( )
{
char *data;
short *sp1, *sp2;
int *ip;
data = (char *)malloc(16);;
sp1 = (short*)(data+3);
sp2 = (short*)(data+5);
ip = (int*)(data+7);
*sp1=10;
*sp2=20;
*ip=30;
fprintf(stderr, "%d %d %d/n", *sp1, *sp2, *ip);
return 0;
}


When this program is compiled with the system compiler on ice
(a 64-bit alpha system), running it will produce a series of
unaligned access error messages.

$ cc -g -o test_unaligned test_unaligned.c
$ ./test_unaligned
Unaligned access pid=16238  va=0x140002101 pc=0x1200011c4 ra=0x120001190 inst=0xa1060000
Unaligned access pid=16238  va=0x140002101 pc=0x1200011d4 ra=0x120001190 inst=0xb1060000
Unaligned access pid=16238  va=0x140002105 pc=0x1200011e8 ra=0x120001190 inst=0xa2b30000
Unaligned access pid=16238  va=0x140002105 pc=0x1200011f8 ra=0x120001190 inst=0xb2b30000
Unaligned access pid=16238  va=0x140002107 pc=0x120001204 ra=0x120001190 inst=0xb2f80000
Unaligned access pid=16238  va=0x140002101 pc=0x12000121c ra=0x2 inst=0xa77b0000
Unaligned access pid=16238  va=0x140002101 pc=0x120001238 ra=0x4 inst=0xa4210000
Unaligned access pid=16238  va=0x140002107 pc=0x120001250 ra=0x4 inst=0xa2940000
10 20 30


The pc value in the unaligned access error line indicates the
address of the program code that generated the error. Using gdb,
it is possible to figure out which line of code the pc address
is associated with (assuming that the program was compiled with
the -g flag, as in the example).

$ gdb test_unaligned
GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "alphaev56-dec-osf4.0d"...
(gdb) info line *0x1200011c4
Line 12 of "test_unaligned.c" starts at address 0x1200011b4
and ends at 0x1200011d8 .
(gdb)


So, using gdb and the error output, we see that the first
unaligned access error resulted from code on line 12 of
test_unaligned.c.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐