原创 Linux C中令人讨厌的段错误

2009-7-7 14:38 2141 4 4 分类: MCU/ 嵌入式

 


作者:孙晓明,华清远见嵌入式学院讲师


同学们在做练习的时候,编译完程序,执行的时候,有时会莫名的出现 “Segment fault”,即段错误,段错误是让许多C程序员都头疼的提示,因为对于这种模糊的提示,很难判断错误在哪里。那么什么事段错误呢?以及怎么发现程序中的段错误以及如何避免发生段错误呢?


1.什么是段错误?


所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了。


通过上面的解释,段错误应该就是访问了不可访问的内存,这个内存区要么是不存在的,要么是受到系统保护的。


2.那什么操作会引起段错误呢?


粗略的分一下类:


1)往受到系统保护的内存地址写数据


有些内存是内核占用的或者是其他程序正在使用,为了保证系统正常工作,所以会受到系统的保护,而不能任意访问。


2)内存越界(数组越界,变量类型不一致等)


3)其他


例如:


<1>定义了指针后记得初始化,在使用的时候记得判断是否为NULL


<2>在使用数组的时候是否被初始化,数组下标是否越界,数组元素是否存在等


<3>在变量处理的时候变量的格式控制是否合理等


3.那么我们如何去发现程序中的段错误呢?


通过学习前人的经验和开发的工具,不断的尝试和研究,找出更恰当的方法来避免、发现并处理它。对于一些常见的地方,我们可以避免,对于一些“隐藏”的地方,我们要发现它,发现以后就要及时处理,避免留下隐患。


用gdb来调试,在运行到段错误的地方,会自动停下来并显示出错的行和行号,gdb也是最常用的,如果需要用gdb调试,记得在编译的时候加上-g参数。

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条