内存调试工具 valgrind
?
来源::
linux下面用c++写代码,在所难免会遇到segmentation fault(段错误)。个人在编写ns扩展模块时候,遇到过很多段错误,虽然运行时刻经常由程序抛出段错误,但是段错误的发生的程序级别的原因多种多样,不过归结到系统级别上,段错误都是由于内存原因引起的(个人总结)。
会造成内存错误的程序级别的原因,也就是我们程序员所经常犯的错误大致可以分为以下几个方面:
1,使用未初始化的指针-这是必然的,指针指空的东西,必然出错。
2,重复删除一个指针-必然,再次删除就会删除一个已经分配给别的程序的数据或者其他。
3,内存冲突-由于程序声明的两块数据区域重叠,造成混乱。
4,混杂的指针错误-只能具体问题具体分析,情况比较复杂。
对于一位刚开始用c++在linux编程的人来说,最常遇到的应该的就是1与2了。当工程规模比较大,程序由小组完成而后整合等的情况下,很容易出现2,3,4的情况。这时候的调试比较麻烦,也需要很多耐心。
我在做的wimax mesh的项目就是这样。对于一个timer的使用,没有初始化,造成的段错误,一目了然。工程进展非常顺利。当工程做到50%时候(11.08号),遇到了一个段错误,结果调试到12.02号才调出来!我就来说一下我的调试历程吧!真是一波三折阿!开始的时候以为是1或者2的情况,反复检查,不是这样。然后怀疑3或者4,结果由于没有使用任何工具,只是在代码中加打印信息,这时候只能把错误定位到transmit(p)这个函数上。但是这个函数我只写了一行,就是
transmit(p)
{
downtarget_-recv(p,(Handle*)NULL);
}
程序在这个地方出错实在让人摸不到头绪,因为再往下执行就不是我代码的问题了,而是下层已有代码甚至是系统代码的问题阿!非常困扰!
然后开始用gdb调试,gdb是一个很好的很强大的调试工具,我用的命令行的,所能完成的功能和vc下的调试工具差不多,只是需要看什么变量就是要用print×来看罢了,不过功能决不比它差。但是我用了gdb只能把错误定位在:
(gdb)bt
#0 0x082d16ba in CheckChannelErrors()
#1 0x082d43a5 in Tcl_Write()
#2 0x081cdb52 in BaseTrace:namdump(this=0x90e09d0)at trace/basetrace.cc:109
#3 0x08137aa4 in CMUTrace:nam_format(this=0x90e10b0,p=0x90fb860,offset=64)at trace/cmu-trace.cc:1123
#4 0x 081384db in CMUTrace:format(this=0x90e10b0,p=0x90fb860,why=0x833ec34---)at trace/cmu-trace.cc:1137
#5 0xin CMUTrace:recv(this=0x90e10b0,p=0x90fb860,h=0x0)at trace/cmu-trace.cc:1239
#6 0x0821e9e7 in Mac802_16:mac_log(this=0x90d1f08,p=0x90fb860)at wimax/mac802_16.h:909
#7 0x 082268e6 in Mac802_16MSS:receive(this=0x90d1f08)at wimax/mac802_16MSS.cc:660
#8 0x08228b08 in WimaxRxTimer:handle(this=0x90d29a4,e=0x90d29b4)at wimax/mac802_16timer.cc:98
#9 0xin Scheduler:dispatch(this=0x8eb6a10,p=0x90d29b4,t=10.017116268588)at common/scheduler.cc:150
#10 0x 0805457e in Scheduler:run(this=0x8eb6a10)at common/scheduler.cc:129
#11 0x 0805485d in Scheduler:command(this=0x8eb6a10,argc=2,argv=0xbf a20730)at common/scheduler.cc:198
#12 0x0828b7ae in TclClass:dispatch_cmd()
#13 0x 082903d0 in OTclDispatch(cd=value optimized out,in=0x8e97
原创力文档

文档评论(0)