




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、.内存调试工具 valgrind来源:linux下面用c+写代码,在所难免会遇到segmentation fault段错误。个人在编写ns扩展模块时候,遇到过很多段错误,虽然运行时刻经常由程序抛出段错误,但是段错误的发生的程序级别的原因多种多样,不过归结到系统级别上,段错误都是由于内存原因引起的个人总结。会造成内存错误的程序级别的原因,也就是我们程序员所经常犯的错误大致可以分为以下几个方面:1,使用未初始化的指针-这是必然的,指针指空的东西,必然出错。2,重复删除一个指针-必然,再次删除就会删除一个已经分配给别的程序的数据或者其他。3,内存冲突-由于程序声明的两块数据区域重叠,造成混乱。4,混
2、杂的指针错误-只能详细问题详细分析,情况比较复杂。对于一位刚开场用c+在linux编程的人来说,最常遇到的应该的就是1与2了。当工程规模比较大,程序由小组完成而后整合等的情况下,很容易出现2,3,4的情况。这时候的调试比较费事,也需要很多耐心。我在做的wimax mesh的工程就是这样。对于一个timer的使用,没有初始化,造成的段错误,一目了然。工程进展非常顺利。当工程做到50%时候11.08号,遇到了一个段错误,结果调试到12.02号才调出来!我就来说一下我的调试历程吧!真是一波三折阿!开场的时候以为是1或者2的情况,反复检查,不是这样。然后疑心3或者4,结果由于没有使用任何工具,只是在代
3、码中加打印信息,这时候只能把错误定位到transmitp这个函数上。但是这个函数我只写了一行,就是transmitpdowntarget_-recvp,Handle*NULL;程序在这个地方出错实在让人摸不到头绪,因为再往下执行就不是我代码的问题了,而是下层已有代码甚至是系统代码的问题阿!非常困扰!然后开场用gdb调试,gdb是一个很好的很强大的调试工具,我用的命令行的,所能完成的功能和vc下的调试工具差不多,只是需要看什么变量就是要用print×来看罢了,不过功能决不比它差。但是我用了gdb只能把错误定位在:gdbbt#0 0x082d16ba in CheckChannelErr
4、ors#1 0x082d43a5 in Tcl_Write#2 0x081cdb52 in BaseTrace:namdumpthis=0x90e09d0at trace/basetrace.cc:109#3 0x08137aa4 in CMUTrace:nam_formatthis=0x90e10b0,p=0x90fb860,offset=64at trace/cmu-trace.cc:1123#4 0x 081384db in CMUTrace:formatthis=0x90e10b0,p=0x90fb860,why=0x833ec34"-"at trace/cmu-t
5、race.cc:1137#5 0x 08138751 in CMUTrace:recvthis=0x90e10b0,p=0x90fb860,h=0x0at trace/cmu-trace.cc:1239#6 0x0821e9e7 in Mac802_16:mac_logthis=0x90d1f08,p=0x90fb860at wimax/mac802_16.h:909#7 0x 082268e6 in Mac802_16MSS:receivethis=0x90d1f08at wimax/mac802_16MSS.cc:660#8 0x08228b08 in WimaxRxTimer:handl
6、ethis=0x90d29a4,e=0x90d29b4at wimax/mac802_16timer.cc:98#9 0x 08054332 in Scheduler:dispatchthis=0x8eb6a10,p=0x90d29b4,t=10.017116268588at common/scheduler.cc:150#10 0x 0805457e in Scheduler:runthis=0x8eb6a10at common/scheduler.cc:129#11 0x 0805485d in Scheduler:commandthis=0x8eb6a10,argc=2,argv=0xb
7、f a20730at common/scheduler.cc:198#12 0x0828b7ae in TclClass:dispatch_cmd#13 0x 082903d0 in OTclDispatchcd=value optimized out,in=0x8e97250,argc=3,argv=0xbfa2077cat otcl.c:434#14 0x 0829712e in TclInvokeStringCommand#15 0x08298c4b in TclEvalObjvInternal#16 0x082c2ef1 in TclExecuteByteCode#17 0x082c6
8、d1c in TclCompEvalObj#18 0x082c2fca in TclExecuteByteCode#19 0x082c6d1c in TclCompEvalObj#20 0x082eec76 in TclObjInterpProc#21 0x082ef092 in TclProcInterpProc#22 0x 08290520 in OTclDispatchcd=value optimized out,in=0x8e97250,argc=2,argv=0xbfa2131cat otcl.c:477#23 0x 0829712e in TclInvokeStringComman
9、d#24 0x08298c4b in TclEvalObjvInternal#25 0x082c2ef1 in TclExecuteByteCode#26 0x082c6d1c in TclCompEvalObj#27 0x082eec76 in TclObjInterpProc#28 0x082ef092 in TclProcInterpProc#29 0x 082903d0 in OTclDispatchcd=value optimized out,in=0x8e97250,argc=2,argv=0xbfa21c2cat otcl.c:434#30 0x 0829712e in TclI
10、nvokeStringCommand#31 0x08298c4b in TclEvalObjvInternal#32 0x 08299207 in Tcl_EvalEx#33 0x082ded12 in Tcl_FSEvalFile#34 0x082e2307 in Tcl_Main#35 0x0804cafc in mainargc=2747804,argv=0x178b62at common/tclAppInit.cc:67这让我更加不解,为什么会在调用ns原有代码的地方出问题呢?后来决定再换一个工具。用valgrind在这里我先贴一下valgrind的用法,我自己搜到的,很详细的。姑且就
11、不自己写了。=Valgrind Valgrind已经在Linux应用程序开发社区中广泛用来调试应用程序。它尤其擅长发现内存管理的问题。它可以检查程序运行时的内存泄漏问题。这个工具目前正由Julian Seward进展开发,并由Paul Mackerras移植到了Power架构上。要安装Valgrind,请从Valgrind的Web站点上下载源代码参阅参考资料。切换到Valgrind目录,并执行下面的命令:#make#make check#make install堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存
12、的现代系统中,它还可以加速我们程序的运行,减少程序停留在交换区中的几率。Valgrind安装1、到 下载最新版valgrind-3.2.3.tar.bz2 2、解压安装包:tar jxvf valgrind-3.2.3.tar.bz2 3、解压后生成目录valgrind-3.2.3 4、cd valgrind-3.2.3 5、./configure 6、Make;make installValgrind使用用法:valgrindoptionsprog-and-argsoptions:常用选项,适用于所有Valgrind工具-tool=name最常用的选项。运行valgr
13、ind中名为toolname的工具。默认memcheck。h help显示帮助信息。-version显示valgrind内核的版本,每个工具都有各自的版本。q quiet安静地运行,只打印错误信息。v verbose更详细的信息,增加错误数统计。-trace-children=no|yes跟踪子线程?no-track-fds=no|yes跟踪翻开的文件描绘?no-time-stamp=no|yes增加时间戳到LOG信息?no-log-fd=number输出LOG到描绘符文件2=stderr-log-file=file将输出的信息写入到filename.PID的文件里,PID是运行程序的进展ID
14、-log-file-exactly=file输出LOG信息到file-log-file-qualifier=VAR获得环境变量的值来做为输出信息的文件名。none-log-socket=ipaddr:port输出LOG到socket,ipaddr:portLOG信息输出-xml=yes将信息以xml格式输出,只有memcheck可用-num-callers=number show number callers in stack traces12-error-limit=no|yes假设太多错误,那么停顿显示新错误?yes-error-exitcode=number假设发现错误那么返回错误代码0
15、=disable-db-attach=no|yes当出现错误,valgrind会自动启动调试器gdb。no-db-command=command启动调试器的命令行选项gdb-nw%f%p适用于Memcheck工具的相关选项:-leak-check=no|summary|full要求对leak给出详细信息?summary-leak-resolution=low|med|high how much bt merging in leak checklow-show-reachable=no|yes show reachable blocks in leak check?noValgrind的错误报告
16、Valgrind的输出格式如下:清单1.Valgrind的输出消息#valgrind du x s.=29404=Address 0x1189AD84 is 0bytes after ablock of size 12 alloc'd=29404=at 0xFFB9964:mallocvg_replace_malloc.c:130=29404=by 0xFEE1AD0:strdupin/lib/tls/libc.so.6=29404=by 0xFE94D30:setlocalein/lib/tls/libc.so.6=29404=by 0x 10001414:mainin/usr/bi
17、n/du=29404=是进程的ID。消息Address 0x1189AD84 is 0bytes after ablock of size 12 alloc'd说明在这个12字节的数组后面没有存储空间了。第二行以及后续几行说明内存是在130行vg_replace_malloc.c的strdup程序中进展分配的。strdup是在libc.so.6库的setlocale中调用的;main调用了setlocale。未初始化的内存最为常见的一个bug是程序使用了未初始化的内存。未初始化的数据可能来源于:未经初始化的变量malloc函数所分配的数据,在写入值之前使用了下面这个例子使用了一个未初始
18、化的数组:清单2.使用未初始化的内存23 int i5;4 5ifi0=06 i1=1;7 return 0;8在这个例子中,整数数组i5没有进展初始化;因此,i0包含的是一个随机数。因此使用i0的值来判断一个条件分支就会导致不可预期的问题。Valgrind可以很容易捕获这种错误条件。当您使用Valgrind运行这个程序时,就会接收到下面的消息:清单3.Valgrind的输出消息#gcc g otest1 test1.c#valgrind./test1.=31363=31363=Conditional jump or move depends on uninitialised values=3
19、1363=at 0x 1000041C:maintest1.c:5=31363=31363=ERROR SUMMARY:1 errors from 1contextssuppressed:7 from 1=31363=malloc/free:in use at exit:0 bytes in 0blocks.=31363=malloc/free:0 allocs,0 frees,0 bytes allocated.=31363=For counts of detected errors,rerun with:-v=31363=No malloc'd blocks-no leaks ar
20、e possible.Valgrind的输出说明,有一个条件分支依赖于文件test1.c中第5行中的一个未初始化的变量。内存泄漏内存泄漏是另外一个常见的问题,也是很多程序中最难判断的问题。内存泄漏的主要表现为:当程序连续运行时,与程序相关的内存或堆变得越来越大。结果是,当这个程序所消耗的内存到达系统的上限时,就会自己崩溃;或者会出现更严重的情况:挂起或导致系统崩溃。下面是一个有内存泄漏bug的例如程序:清单4.内存泄漏例如1 int mainvoid23 char*p1;4 char*p2;5 6p1=char*malloc512;7 p2=char*malloc512;8 9p1=p2;10
21、 11 freep1;12 freep2;13上面的代码分别给字符指针p1和p2分配了两个512字节的内存块,然后将指向第一个内存块的指针设置为指向第二个内存块。结果是,第二个内存块的地址丧失了,并导致内存泄漏。在使用Valgrind运行这个程序时,会返回如下的消息:清单5.Valgrind的输出消息#gcc g otest2 test2.c#valgrind./test2.=31468=Invalid free/delete/delete=31468=at 0xFFB9FF0:freevg_replace_malloc.c:152=31468=by 0x 100004B0:maintest2
22、.c:12=31468=Address 0x 11899258 is 0bytes inside ablock of size 512 free'd=31468=at 0xFFB9FF0:freevg_replace_malloc.c:152=31468=by 0x 100004A4:maintest2.c:11=31468=31468=ERROR SUMMARY:1 errors from 1contextssuppressed:7 from 1=31468=malloc/free:in use at exit:512 bytes in 1blocks.=31468=malloc/f
23、ree:2 allocs,2 frees,1024 bytes allocated.=31468=For counts of detected errors,rerun with:-v=31468=searching for pointers to 1not-freed blocks.=31468=checked 167936 bytes.=31468=31468=LEAK SUMMARY:=31468=definitely lost:512 bytes in 1blocks.=31468=possibly lost:0 bytes in 0blocks.=31468=still reacha
24、ble:0 bytes in 0blocks.=31468=suppressed:0 bytes in 0blocks.=31468=Use-leak-check=full to see details of leaked memory.正如您可以看到的一样,Valgrind报告说这个程序中有512字节的内存丧失了。非法写/读这种情况发生在程序试图对一个不属于程序本身的内存地址进展读写时。在有些系统上,在发生这种错误时,程序会异常完毕,并产生一个段错误。下面这个例子就是一个常见的bug,它试图读写一个超出数组边界的元素。清单6.非法读写1 int main2 int i,*iw,*ir;3 4
25、iw=int*malloc10*sizeofint;5 ir=int*malloc10*sizeofint;6 78 fori=0;i 11;i+9 iwi=i;10 11 fori=0;i 11;i+12 iri=iwi;13 14 freeiw;15 freeir;16从这个程序中我们可以看出,对于iw10和ir10的访问都是非法的,因为iw和ir都只有10个元素,分别是从0到9。请注意int iw10和iw=int*malloc10*sizeofint是等效的-它们都是用来给一个整数数组iw分配10个元素。当您使用Valgrind运行这个程序时,会返回如下的消息:清单7.Valgrind
26、的输出消息#gcc g otest3 test3.c#valgrind./test3.=31522=Invalid write of size 4=31522=at 0x 100004C0:maintest3.c:9=31522=Address 0x 11899050 is 0bytes after ablock of size 40 alloc'd=31522=at 0xFFB9964:mallocvg_replace_malloc.c:130=31522=by 0x 10000474:maintest10.c:4=31522=31522=Invalid read of size 4
27、=31522=at 0x 1000050C:maintest3.c:12=31522=Address 0x 11899050 is 0bytes after ablock of size 40 alloc'd=31522=at 0xFFB9964:mallocvg_replace_malloc.c:130=31522=by 0x 10000474:maintest10.c:4=31522=31522=ERROR SUMMARY:2 errors from 2contextssuppressed:7 from 1=31522=malloc/free:in use at exit:0 by
28、tes in 0blocks.=31522=malloc/free:2 allocs,2 frees,84 bytes allocated.=31522=For counts of detected errors,rerun with:-v=31522=No malloc'd blocks-no leaks are possible.在test3.c的第9行发现一个非法的4字节写操作,在第12行发现一个非法的4字节读操作。Valgrind也可以帮助判断内存误用的问题,例如:读/写已经释放的内存C+环境中错误地使用malloc/new与free/delete的配对下面这个列表介绍了POW
29、ER架构上Valgrind的状态:memcheck和addrcheck工具都可以很好地工作。然而,其他工具还没有进展大量的测试。另外,Helgrind一个数据竞争的检测程序在POWER上尚不能使用。所有的32位PowerPC?用户形式的指令都可以支持,除了两条非常少用的指令:lswx和stswx。详细来说,所有的浮点和AltivecVMX指令都可以支持。Valgrind可以在32位或64位PowerPC/Linux内核上工作,但是只能用于32位的可执行程序。有关Valgrind内存调试的更多信息,请访问Valgrind HOW TO站点。还可以参阅Steve Best的"Debugg
30、ing Memory Problems"Linux Magazine,2003年5月。参考资料中有它们的链接除了Valgrind之外,还可以使用其他几个内存调试工具;例如,Memwatch和Electric Fence。=上述的例子足以应付我们日常遇到的内存错误。那么我来说说我是怎么用valgrind调试我的程序的。用命令:tengdalocalhost tcl$valgrind-tool=memcheck-leak-check=full-db-attach=yes ns sss.tcl=26507=Memcheck,a memory error detector.=26507=Co
31、pyrightC2002-2007,and GNU GPL'd,by Julian Seward et al.=26507=Using LibVEX rev 1732,a library for dynamic binary translation.=26507=CopyrightC2004-2007,and GNU GPL'd,by OpenWorks LLP.=26507=Using valgrind-3.2.3,a dynamic binary instrumentation framework.=26507=CopyrightC2000-2007,and GNU GPL
32、'd,by Julian Seward et al.=26507=For more details,rerun with:-v=26507=然后出现调试信息:Mac 2has transmit apacket at 10.015894=26507=26507=Invalid read of size 4=26507=at 0x82D439B:Tcl_Writein/home/tengda/ns-allinone-2.31/ns-2.31/ns=26507=by 0x81CDB51:BaseTrace:namdumpbasetrace.cc:109=26507=by 0x 813768E
33、:CMUTrace:nam_formatPacket*,intcmu-trace.cc:1034=26507=by 0x81384DA:CMUTrace:formatPacket*,char const*cmu-trace.cc:1137=26507=by 0x 8138750:CMUTrace:recvPacket*,Handler*cmu-trace.cc:1239=26507=by 0x 822513C:Mac802_16MSS:transmitPacket*mac802_16MSS.cc:569=26507=by 0x82149B2:Mac802_16:send_ncfgmac802_
34、16.cc:1086=26507=by 0x8228EFB:NcfgTimer:expireEvent*mac802_16timer.cc:418=26507=by 0x8052A2C:TimerHandler:handleEvent*timer-handler.cc:99=26507=by 0x 8054331:Scheduler:dispatchEvent*,doublescheduler.cc:150=26507=by 0x 805457D:Scheduler:runscheduler.cc:129=26507=by 0x 805485C:Scheduler:commandint,char const*const*scheduler.cc:198=26507=Address 0x54D4540 is 0bytes inside ablock of size 28 free'd=26507=at 0x40050FF:freevg_replace_malloc.c:233=26507=by 0x83125AC:TclpFreein/home/tengda/ns-allinone-2.31/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国绝缘制品市场十三五规划与投资战略研究报告
- 2025-2030年中国红木市场竞争格局及发展趋势分析报告
- 2025-2030年中国精密减速器市场发展现状及前景趋势分析报告
- 2025-2030年中国碲行业运行状况及发展趋势分析报告
- 2025年辽宁省安全员C证考试(专职安全员)题库附答案
- 2025-2030年中国皮带输送机市场运行状况及发展前景分析报告
- 2025-2030年中国电解铜行业发展潜力规划研究报告
- 重庆邮电大学《电脑辅助设计》2023-2024学年第二学期期末试卷
- 成都信息工程大学《艺用人体解剖学》2023-2024学年第二学期期末试卷
- 泰山学院《财政政策与货币政策》2023-2024学年第二学期期末试卷
- 生物医药行业市场前景及投资研究报告:代谢相关脂肪肝炎(MASHNASH)无药可治巨大市场需求
- 2024年医药卫生考试-静脉治疗知识笔试参考题库含答案
- 《输变电工程三维协同设计规范》
- 保洁员岗位安全知识培训
- 第二单元大单元教学设计 2023-2024学年统编版高中语文必修上册
- JTT513-2004 公路工程土工合成材料 土工网
- 2024年高考语文复习:文言文断句专项练习题汇编(含答案解析)
- 中医科医院感染管理制度(全新版)
- 2023广东省广州市一模英语真题及答案
- 屈原【六幕话剧】郭沫若
- 茶叶抖音方案
评论
0/150
提交评论