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;