stack corruption,segmentation fault和bus error<core dump>错误分析

stack corruption:栈摧毁错误

此类错误一般是数组越界造成的。

 

segmentation fault:段错误 

一般有以下原因容易造成段错误:

   1)指针:

       指针为空"NULL",或者指针未初始化就使用,指针使用完后未释放

  2)内存(超出分配的内存空间):

       对数组操作不当,数组越界;对字符串操作不当(比如在使用strcpy函数时),字符串空间越界;对动态内存操作不当,内存越界

 

bus error:总线错误

此类错误目前遇到的情况都是因为内存未对齐造成的,内存对齐问题经常发生在嵌入式中,因为跟平台相关。

内存对齐问题

1)数组(或者数组元素)的数据类型强制转换造成的。

     虽然编译时只是警告,没有错误。编译通过了,但是实际运行时,不同类型的变量所占内存大小不同,强制转换就会造成内存对齐问题。

     比如以下代码:

int stringtobytearray(char* uuid, uint8_t* uuid_b){
int count;
count=sscanf(uuid,"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",&uuid_b[0],&uuid_b[1],&uuid_b[2],&uuid_b[3],&uuid_b[4],&uuid_b[5],&uuid_b[6],&uuid_b[7],\
&uuid_b[8],&uuid_b[9],&uuid_b[10],&uuid_b[11],&uuid_b[12],&uuid_b[13],&uuid_b[14],&uuid_b[15]);
return count;

}

分析:%2x期望的数据类型是int类型的,32位,四个字节。所以访问第i个数组元素时,访问的内存地址应该是:(首地址+4*i),或者&array[i*4];但是实际上面代码中,数组类型是uint8_t 类型,只占一个字节。内存地址是按照1字节对齐的。这样就会造成内存对齐问题出现。

解决方案如下

方案1)以四字节的整数倍,访问内存

int stringtobytearray_arm(char* uuid, uint8_t* uuid_b){
int count;
count=sscanf(uuid,"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",&uuid_b[0],&uuid_b[4],&uuid_b[8],&uuid_b[12],&uuid_b[16],&uuid_b[20],&uuid_b[24],&uuid_b[28],\
&uuid_b[32],&uuid_b[36],&uuid_b[40],&uuid_b[44],&uuid_b[48],&uuid_b[52],&uuid_b[56],&uuid_b[60]);
return count;

}

方案2)保持类型一致,将%2x改成%hhu,%hhu对应的数据类型是一字节的

 

注意:1)对于标准库中的函数,变量类型,数据结构混合使用一般不会出现bus error错误;但一旦涉及到平台相关的函数,变量,结构体则容易发生内存对齐问题。

         2)不要忽略编译过程中编译器发出的警告,这些警告可能对编译不会造成什么影响,但是运行时往往会造成困扰。 

        3)一定要注意避免平台差异,使代码更通用。

        

posted on 2016-09-09 13:31  happy刘艺  阅读(1511)  评论(0编辑  收藏  举报

导航