免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2180 | 回复: 9

[C] 'UNALIGN' Error/Exception Cause System Reboot [复制链接]

论坛徽章:
0
发表于 2015-06-03 09:08 |显示全部楼层
某些板子的CPU有某些限制,不能在奇数地址访问short/int型的数据,一旦访问,就会有'UNALIGN'的错误或异常,导致板子重启。

void parseMessage(char* pMsg)
{
    ...
    UINT16 userID = (*(UINT16 *)((unsigned long)pMsg+ LTMSG_USERID_POS+2));//System Crashs Periodically
    ...
   
}

上面的代码LTMSG_USERID_POS+2是偶数,pMsg是从另一块板子上通过malloc动态分配,然后发到本板,在本板上的消息体指针,可能是奇数地址也可能是偶数地址,奇数地址时发生Reboot.  原始消息是通过offset逐个BYTE赋值的,并没有具体的结构体定义相关联(所以使用字节强制对齐,不可行),接收到消息后,会有像上面一样一次同时访问多个BYTE的情况。

从编程的角度来看我们的code都是对的,请各位帮忙看看能在什么地方避免该问题?

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
发表于 2015-06-03 09:20 |显示全部楼层
memcpy一下就ok了。

另外,因为没考虑对齐导致出错,很难认同“从编程的角度来看我们的code都是对的”。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2015-06-03 09:48 |显示全部楼层
指定结构按1字节对齐,通过结构指针访问,编译器会帮你处理

论坛徽章:
0
发表于 2015-06-03 10:14 |显示全部楼层
memcpy有一样的问题

unsigned int MsgLen = 100;
unsigned int Slot = 0x21101;
unsigned short UserId = 0x1234;

char *pMsg=malloc(100);

*pMsg++ = MsgLen;
*pMsg++ = Slot>>24;
*pMsg++ = Slot>>16;
*pMsg++ = Slot>>8;
*pMsg++ = Slot;
...
*pMsg++ = UserId>>8;
*pMsg++ = UserId;
...

pMsg是一块连续内存,像上面一样赋值,请问怎么考虑字节对齐?

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
发表于 2015-06-03 10:24 |显示全部楼层
不要老怪按字节赋值,你取的时候保证没问题就ok了。

UINT16  userID;
memcpy(&userID, pMsg + ..., sizeof(UINT16));

论坛徽章:
0
发表于 2015-06-04 08:36 |显示全部楼层
回复 3# hellioncu

按照1字节对齐,也会发生在奇数地址访问short、int或long等型数据的情况,这样遇到我们这种特殊的CPU照样Crash.

typedef struct
{
char operation __attribute__ ((aligned (1));
unsigned short slot __attribute__ ((aligned (1));//MSG_TYPE型变量起始地址base如果是奇数,则slot的地址也是奇数,所以要按照2字节对齐
...
}MSG_TYPE;



   

论坛徽章:
0
发表于 2015-06-04 08:40 |显示全部楼层
回复 5# zhaohongjian000

说过了,我们的这种CPU遇到奇数地址访问short/int/long型数据的时候就会Crash, 你的memcpy的原地址是奇地址时,已经验证过了,也有同样的问题


   

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2015-06-04 08:50 |显示全部楼层
hzy2hzy 发表于 2015-06-04 08:36
回复 3# hellioncu

按照1字节对齐,也会发生在奇数地址访问short、int或long等型数据的情况,这样遇到我 ...


如果真是那样,那应该是你编译器没有支持好,本来应该生成按字节复制的指令。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2015-06-04 08:52 |显示全部楼层
hzy2hzy 发表于 2015-06-04 08:40
回复 5# zhaohongjian000

说过了,我们的这种CPU遇到奇数地址访问short/int/long型数据的时候就会Crash ...


memcpy一般的实现是对于非对齐的部分按字节复制,对齐的按int/long复制以加快速度,你这都会出错,用的啥编译器?

论坛徽章:
0
发表于 2015-06-11 21:07 |显示全部楼层
回复 9# hellioncu

长知识了!!!

前面修改为memcpy不行,是因为还有其它地方用类型强转了,没有发现!


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP