欢迎来到天天文库
浏览记录
ID:8798475
大小:54.50 KB
页数:7页
时间:2018-04-08
《ap简单定位段错误的方法》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、AP简单定位段错误的方法引言简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址.一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会
2、产生相应的异常保护,于是segmentationfault就出现了.在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的1)访问系统数据区,尤其是往 系统保护的内存地址写数据最常见就是给一个指针以0地址2)内存越界(数组越界,变量类型不一致等)访问到不属于你的内存区域解决方法我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就"段错误"这个内存访问越界的错误谈谈如
3、何快速定位这些"段错误"的语句。下面将就以下的一个存在段错误的程序介绍几种调试方法: 1 dummy_function(void) 2 { 3 unsignedchar*ptr=0x00; 4 *ptr=0x00; 5 } 6 7 intmain(void) 8 { 9 dummy_function(); 10 11 return0; 12 }作为一个熟练的C/C++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个内存区域通常是不可访
4、问的禁区,当然就会出错了。我们尝试编译运行它:xiaosuo@gentuxtest$./a.out段错误果然不出所料,它出错并退出了。1.利用gdb逐步查找段错误:这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程序,所以我们加上“-g-rdynamic"的参数进行编译,然后用gdb调试运行这个新编译的程序,具体步骤如下:xiaosuo@gentuxtest$gcc-g-rdynamicd.cxiaosuo@gentuxtest$gdb./a.outGNUgdb6.5Copyright(C)2006FreeSoftwareFoundation,Inc.GDBisf
5、reesoftware,coveredbytheGNUGeneralPublicLicense,andyouarewelcometochangeitand/ordistributecopiesofitundercertainconditions.Type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforGDB. Type"showwarranty"fordetails.ThisGDBwasconfiguredas"i686-pc-linux-gnu"...Usinghostlibthread_dblibrary"/lib
6、/libthread_db.so.1".(gdb)rStartingprogram:/home/xiaosuo/test/a.outProgramreceivedsignalSIGSEGV,Segmentationfault.0x08048524indummy_function()atd.c:44 *ptr=0x00;(gdb) 哦?!好像不用一步步调试我们就找到了出错位置d.c文件的第4行,其实就是如此的简单。从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。通过进一步的查阅文档(man7signal),我们知道S
7、IGSEGV默认handler的动作是打印”段错误"的出错信息,并产生Core文件,由此我们又产生了方法二。2.分析Core文件:Core文件是什么呢?The defaultactionofcertainsignalsistocauseaprocesstoterminateandproduceacoredumpfile,adiskfilecontaininganimageoftheprocess'
此文档下载收益归作者所有