从一个EXC_ARM_DA_ALIGN的crash来看ios3.2以后内存对齐问题
2013-08-05 11:03
453 查看
/article/10539810.html
今天在Iphone4调试的时候,遇到一个EXC_ARM_DA_ALIGN。用Iphone 3G(IOS3.1.2)调试之则不出现。因为出问题的代码乃一个库文件里面的,函数大致如下:
void f(const char * pBuffer, uint64_t * pDesLLong)
{
(*(uint64_t *)pDesLLong) = (*(uint64_t *)pBuffer);
...
}
查看crash log文件,发现是由于产生了一个EXC_ARM_DA_ALIGN 的 Exception。google之,找到一位老外兄弟言:IOS3.2以及之后的版本,开发者需要考虑内存对齐的问题。http://byteclub.com/blog/44-development/85-memory-alignment-errors-on-iphone-os-3-2
那么,它是几字节对齐呢?根据上面这位牛哥提供的资源,查到了这样一篇比较系统的文档,知道它是4字节对齐得(word)(https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html)
那么问题就很明显了:如果上面那两个指针pBuffer和pDestLong所指的地址不是4的倍数,就会触发一个对齐的异常EXC_ARM_DA_ALIGN。那么这个问题怎么解决呢?前面的文档中言,使用memcpy来代替type casting来做赋值。于是我将代码改为:
memcpy((char*)pDestLong, (char*)pBuffer, sizeof(uing64_t));
在Debug版本下运行之,果然有效。可是当我编出一个Release版本的时候,问题又出现了。为何?
第一印象一定是memcpy是否被优化掉了。于是google “memcpy optimize”,发现以下这个优化代码:
void * memcpy(void * dst, void const * src, size_t len)
{
long * plDst = (long *) dst;
long const * plSrc = (long const *) src;
if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))
{
while (len >= 4)
{
*plDst++ = *plSrc++;
len -= 4;
}
}
char * pcDst = (char *) plDst;
char const * pcDst = (char const *) plSrc;
while (len--)
{
*pcDst++ = *pcSrc++;
}
return (dst);
}
第一句话这个赋值,如果传入的指针不是一个四字节对齐的指针,即所指地址不是4的倍数,那么就会引发一个EXC_ARM_DA_ALIGN。如果真是这样的话,解决方案就必须自己写一个老版本的memcpy函数了:
void * memcpy(void * dst, void const * src, size_t len)
{
char * pDst = (char *) dst;
char const * pSrc = (char const *) src;
while (len--)
{
*pDst++ = *pSrc++;
}
return (dst);
}
今天在Iphone4调试的时候,遇到一个EXC_ARM_DA_ALIGN。用Iphone 3G(IOS3.1.2)调试之则不出现。因为出问题的代码乃一个库文件里面的,函数大致如下:
void f(const char * pBuffer, uint64_t * pDesLLong)
{
(*(uint64_t *)pDesLLong) = (*(uint64_t *)pBuffer);
...
}
查看crash log文件,发现是由于产生了一个EXC_ARM_DA_ALIGN 的 Exception。google之,找到一位老外兄弟言:IOS3.2以及之后的版本,开发者需要考虑内存对齐的问题。http://byteclub.com/blog/44-development/85-memory-alignment-errors-on-iphone-os-3-2
那么,它是几字节对齐呢?根据上面这位牛哥提供的资源,查到了这样一篇比较系统的文档,知道它是4字节对齐得(word)(https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html)
那么问题就很明显了:如果上面那两个指针pBuffer和pDestLong所指的地址不是4的倍数,就会触发一个对齐的异常EXC_ARM_DA_ALIGN。那么这个问题怎么解决呢?前面的文档中言,使用memcpy来代替type casting来做赋值。于是我将代码改为:
memcpy((char*)pDestLong, (char*)pBuffer, sizeof(uing64_t));
在Debug版本下运行之,果然有效。可是当我编出一个Release版本的时候,问题又出现了。为何?
第一印象一定是memcpy是否被优化掉了。于是google “memcpy optimize”,发现以下这个优化代码:
void * memcpy(void * dst, void const * src, size_t len)
{
long * plDst = (long *) dst;
long const * plSrc = (long const *) src;
if (!(src & 0xFFFFFFFC) && !(dst & 0xFFFFFFFC))
{
while (len >= 4)
{
*plDst++ = *plSrc++;
len -= 4;
}
}
char * pcDst = (char *) plDst;
char const * pcDst = (char const *) plSrc;
while (len--)
{
*pcDst++ = *pcSrc++;
}
return (dst);
}
第一句话这个赋值,如果传入的指针不是一个四字节对齐的指针,即所指地址不是4的倍数,那么就会引发一个EXC_ARM_DA_ALIGN。如果真是这样的话,解决方案就必须自己写一个老版本的memcpy函数了:
void * memcpy(void * dst, void const * src, size_t len)
{
char * pDst = (char *) dst;
char const * pSrc = (char const *) src;
while (len--)
{
*pDst++ = *pSrc++;
}
return (dst);
}
相关文章推荐
- crash:EXC_ARM_DA_ALIGN(关于内存对齐,memcpy)
- iOS真机上的EXC_ARM_DA_ALIGN问题
- EXC_ARM_DA_ALIGN问题
- EXC_ARM_DA_ALIGN问题
- EXC_ARM_DA_ALIGN问题
- ios平台上一个由字节对齐问题导致的crash
- ARM内存边界对齐以及sizeof问题
- Arm结构体gcc内存边界对齐问题(zt)
- 字节对齐导致的iOS EXC_ARM_DA_ALIGN崩溃
- 关于pragma pack的用法--------------C 中的内存对齐问题(转载)
- arm-linux-gcc 与 gcc 关于字节对齐问题
- C struct结构体内存对齐问题
- iOS上如何让按钮文本左对齐问题
- 深度探索c++对象模型读书笔记:Data语意学-继承与Data member中内存对齐问题
- 关于 struct 和 union 存储时内存边界对齐的问题(二)
- IOS递归加载多资源(Image)的crash问题【creator 1.4.2】
- C语言 结构体的内存对齐问题与位域
- iOS 8以后 定位手动授权问题
- 大端和小端--内存对齐问题
- 内存对齐问题总结