ARMv5指令集的CPU(一般是arm9架构)默认不支持非对齐内存访问,ARMv6及以上的CPU默认支持处理大部分的非对齐内存地址访问。对齐指的是起始地址是一个word长度的整数倍,通常是4字节对齐。
前几天交叉编译crtmpserver到arm9下。编译通过,但是运行的时候,总是提示Alignment trap错误,如下:
[ 10.038069] Alignment trap: not handling instruction ed958a00 at [<b365dae0>]
[ 10.038981] Unhandled fault: alignment exception (0x221) at 0x72466cdf
该错误有时会影响程序的运行。有时不会,但这就像一颗定时炸弹一样,一定要解决。
修改makefile,加入-ggdb,去掉编译优化,重新编译。(此步可不做)
编译完毕,在gdb下运行,依然提示Alignment trap,并且gdb没有任何反应。
按照设想,操作系统应该能捕获到这个错误,然后通过信号的方式传递给gdb,gdb再中断停下来。
但是事实上并没有按照我的设想运行,为什么呢?通过查找资料,发现cpu在处理内存对齐的时候,有几种方式可以设置。
cat /proc/cpu/alignment
User: 1
System: 0
Skipped: 0
Half: 0
Word: 1
DWord: 0
Multi: 0
User faults: 3 (fixup+warn)
我的嵌入式linux系统下的默认处理方式是第3级处理方式:修复+警告。
0 - ignore
1 - warn
2 - fixup
3 - fixup+warn
4 - signal
5 - signal+warn (需要这个)
于是修改为:echo 5 > /proc/cpu/alignment,这样就会给内核一个信号。
再在gdb下面重新运行,当再次出现该提示时,gdb捕获到该信息,然后bt, 可以查看出现问题的位置。
最终发现代码中问题所在:
第一次:将char类型数据的指针强制转换成 float* 所导致。
http://192.168.199.199/svn/bvs3d_hd/vsdk/apps/trunk/H002_Chery_HJ7D
svn版本号:23251
第二次:如下的结构体从一个头文件移到另一个头文件(该头文件被多个类包含),出现此文章的问题。
pthread_mutex_t出的问题,将结构体移回原文件,问题解决。
typedef struct
{
int inited_flag;
int pending_reply; //indicate that the command hasn't receive the reply and waiting for reply.
unsigned int cmd_id; //the command id.
//These two var are const to a command type transaction.
int resend_timeout;
int max_retry_count;
int ms_from_lastsend; //the time from last send the command, in ms.
int retry_count; //the resend count the command has been sent.
SIMULATOR_PROTOCOL_PACKET command;
pthread_mutex_t mutex;
}COMMAND_TRANSACTION;