zoukankan      html  css  js  c++  java
  • EXC_ARM_DA_ALIGN问题

    同事在做iOS的release版本时出现了一个EXC_ARM_DA_ALIGN的问题,原因是ARM要求内存4字节对齐。

    参考以下几个网页梳理来龙去脉如下:

    (1)https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html

    (2)http://blog.csdn.net/slay_cn/article/details/6221637

    (3)http://www.cocos2d-x.org/boards/6/topics/18183?r=22190

    按照(1)的说法,这个问题常见于对一个字节流进行处理解析,比如从网络收到一个数据包,读入本地缓存后进行处理,头两个字节是一个short标志,接下来四个字节是一个int参数,所以将指向这个位置的指针直接cast成int*来读取数据——于是问题就出现了,当读int*时,ARM要求字节对齐,而此时不对齐。则有可能出现EXC_ARM_DA_ALIGN异常而崩溃。

    治本的解决方法是设计的时候就让数据对齐,可是数据有时候也不是我们设计的,这时候有两种解决方案。

    方案1是在指针定义时加上编译器指令PACKED,则编译器在遇到此关键字时就不再要求字节对齐,而是自行进行正确的处理。

    方案2是使用memcpy逐字节拷贝来绕过直接的int*指针读取。

    在我们的项目中,事实上引擎作者已经使用了方案2的做法来进行处理。那么为什么还有问题呢?按照(2)的说法,是因为memcpy被优化掉了,在优化的版本中,将指针转成long型,4个4个字节的进行复制,于是又出现了字节对齐的问题。解决方案是另写一个低效的memcpy原始版本代替。

    再进一步搜索,发现(3)中提到,引擎作者已经发现了这个问题并加以更新,他们的解决方案仍然是使用系统自带的memcpy,但是在传入参数时,先将参数转成void*类型。根据注释来看,如果传入的参数是特定类型,则编译器会自动采用前面说到的优化版本,但是如果传入void*,那么编译器就会采用通用版本,从而避免了问题的出现。

    这个问题到此告一段落,但是比较困惑的问题是,这个问题并不是时刻出现的,debug不出现而release出现这可以理解。可在我们的项目里,之前一直没有出错,突然有一天就出错了,同时另一个同事机器上同样的代码就没有出错。。。。。。

    另外以前做另一个iPad项目时,有遇到过3D模型从3D Max导出时一定要选择字节对齐,否则一烧到真机运行必定crash,还是必定crash好解决啊~~

  • 相关阅读:
    Eclipse查看某个方法被哪些类调用
    ServletContextListener的作用
    ServletContextListener使用详解(监听Tomcat启动、关闭)
    通用测试用例大全
    Spring常用注解汇总
    Spring @Lazy
    Qt 事件处理 快捷键(重写eventFilter的函数,使用Qt::ControlModifier判断)
    Qt之使用setWindowFlags方法遇到的问题(追踪进入QWidget的源码分析原因,最后用WINAPI解决问题)good
    delphi idhttp 实战用法(TIdhttpEx)
    delphi 线程教学第一节:初识多线程(讲的比较浅显),还有三个例子
  • 原文地址:https://www.cnblogs.com/unionfind/p/2932262.html
Copyright © 2011-2022 走看看