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

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)一定要注意避免平台差异,使代码更通用。

时间: 2024-10-20 05:26:46

segmentation fault和bus error<core dump>错误分析的相关文章

段错误Segment Fault定位,即core dump文件与gdb定位

使用C++开发系统有时会出现段错误,即Segment Fault.此类错误程序直接崩溃,通常没有任何有用信息输出,很难定位bug,因而无从解决问题.今天我们介绍core dump文件,并使用gdb进行调试,以此来定位段错误问题.此文同时用以备忘. 一.core dump Core dump也称核心转储, 当程序运行过程中异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 称之为core dump文件. 系统默认不生成core dump文件,可以使用ulimit命令进行查看和设

【Z】段错误Segment Fault定位,即core dump文件与gdb定位

使用C++开发系统有时会出现段错误,即Segment Fault.此类错误程序直接崩溃,通常没有任何有用信息输出,很难定位bug,因而无从解决问题.今天我们介绍core dump文件,并使用gdb进行调试,以此来定位段错误问题.此文同时用以备忘. 一.core dump Core dump也称核心转储, 当程序运行过程中异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 称之为core dump文件. 系统默认不生成core dump文件,可以使用ulimit命令进行查看和设

iOS 开发报错 clang: error: unable to execute command: Segmentation fault: 11

ios开发报错 ld: can't link with a main executable file '/Users/apple/Library/Developer/Xcode/DerivedData/LePaiDemo-ftsuwgzvjdjwzghgkuefbzvdkvey/Build/Products/Debug-iphoneos/LePaiDemo.app/LePaiDemo' for architecture armv7 clang: error: unable to execute

app打包时报错unable to execute command: Segmentation fault: 11

问题:打包时报错   clang: error:unable to execute command: Segmentation fault: 11 clang: error:linker command failed due to signal (use -v to see invocation) app在上架的时候遇到这个报错问题,一开始以为是证书或者是配置描述文件哪里出错了.作为新手,在试了好多方法依然无法解决之后,只能无奈按照app上架流程又完完全全的重新过了一遍,在点击Archive后的

bus error(总线错误)

转自 http://blog.csdn.net/todd911/article/details/8813321 在<C专家编程>中提到了总线错误bus error(core dumped). 总线错误几乎都是由于未对齐的读或写引起的. 它之所以称为总线错误,是因为出现未对齐的内存访问请求时,被堵塞的组件就是地址总线.对齐的意思就是数据项只能存储在地址是数据项大小的整倍数的内存位置上. 现代的计算机架构中,尤其是RISC架构,都需要字对齐,因为与任意的对齐有关的额外逻辑都会使内存系统更大且更慢.

Segmentation fault(Core Dump)

Segmentation fault 这个提示还是比较常见的,这个提示就是段错误,这是翻译还是十分恰当的. Core Dump 有的时候给我们呈现的翻译很有趣是"吐核",但是实际上比较贴切的翻译是核心转储(是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件.这种信息往往用于调试),这个"吐核"的产生和王安博士有着一些关联,其实"吐核"这个词形容的很恰当,就是核心内存吐出来. 出现这种错误

Linux程序Segmentation fault (core dumped)

1 问题原因 Segmentation fault (core dumped)多为内存不当操作造成.空指针.野指针的读写操作,数组越界访问,破坏常量等.对每个指针声明后进行初始化为NULL是避免这个问题的好办法.排除此问题的最好办法则是调试. 更为详细的原因: (1)内存访问越界 a) 由于使用错误的下标,导致数组访问越界b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符c) 使用strcpy, strcat, sprintf, strcmp, strcas

Segment fault及LINUX core dump详解

源自:http://andyniu.iteye.com/blog/1965571 core dump的概念: A core dump is the recorded state of the working memory of a computer program at a specific time, generally when the program has terminated abnormally (crashed). In practice, other key pieces of

Segment fault及LINUX core dump详解 (zz)

C 程序在进行中发生segment fault(core dump)错误,通常与内存操作不当有关,主要有以下几种情况: (1)数组越界. (2)修改了只读内存. (3)scanf("%d",n),n不是指针. …… 1. 前言: 有的程序可以通过编译, 但在运行时会出现Segment fault(段错误). 这通常都是指针错误引起的. 但这不像编译错误一样会提示到文件->行, 而是没有任何信息, 使得我们的调试变得困难起来. 2. gdb: 有一种办法是, 我们用gdb的step