Linux中指针强制转换引发Alignment trap告警

一、现象

ARM9平台运行应用程序时,当有指针强制转化时,总是输出Alignment trap告警

二、原理

这是访问了非对齐的内存。那什么是对齐的内存?现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。

ARMv5指令集的CPU(一般是arm9架构)默认不支持非对齐内存访问,ARMv6及以上的CPU默认支持处理大部分的非对齐内存地址访问

三、分析

知道了ARM平台的问题,我们该怎么处理呢?经过查找资料,如下:
ARMv5指令集的CPU(一般是arm9架构)默认不支持非对齐内存访问,ARMv6及以上的CPU默认支持处理大部分的非对齐内存地址访问。对齐指的是起始地址是一个word长度的整数倍,通常是4字节对齐。

通过设置/proc/cpu/alignment文件内容可修改内核中对非对齐地址访问的处理。

root@(none):~# cat /proc/cpu/alignment
User:           3905290
System:         0
Skipped:        0
Half:           0
Word:           0
DWord:          2672136
Multi:          1233154
User faults:    0 (ignore)

这个文件中最后一行"User faults"即是内核中如何处理非对齐的内存地址访问,这个值是一个位图:

0 - ignore
1 - warn
2 - fixup
3 - fixup+warn
4 - signal
5 - signal+warn 

WARN:只给出“Alignment trap”警告。
FIXUP:尝试正确处理非对齐的内存地址。
SIGNAL:发生非对齐地址访问时,发送SIGBUS信号通知相应进程。
几种处理方式可以进行组合,例如设置为(UM_WARN | UM_FIXUP),就是在fixup的同时给出警告信息。如果设置为0则为ignore。

对于ARMv5的CPU,User faults的值默认是0,即忽略非对齐的地址访问,这时如果进程访问了非对齐的地址,就会导致程序执行异常。如果程序中存在非对齐的地址访问,可以设置为fixup:

echo 2 > /proc/cpu/alignment

这样的话,内核就会做额外的工作,以使访问非对齐内存地址可以得到正确的结果

对于ARMv6及以上的CPU,CPU本身就要求支持对非对齐地址访问的处理,因此基本不用关心/proc/cpu/alignment里设置的值,不过对于像LDM, STM, LDRD和STRD这些复合指令进行的非对齐地址访问,仍需要软件协助处理,在这些CPU中,/proc/cpu/alignment默认设置为2(fixup)

四、补充

平时在写代码的时候,在内存访问上,尽量使用memcmp,memcpy,memset等函数,而不要为了方便,直接对指针内容进行访问。这样的代码在x86上可能没问题,但是运行到arm上,就可能会出问题。
 

参考:

Alignment trap 解决方法  【转 结合上一篇

ARM Linux中的非对齐内存访问(Alignment trap警告的原因)_落尘纷扰的专栏-CSDN博客_alignment trap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值