How-To Find the Source of "Unaligned Access"

 

 

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值