VC中的一些调试技巧Word文件下载.docx
《VC中的一些调试技巧Word文件下载.docx》由会员分享,可在线阅读,更多相关《VC中的一些调试技巧Word文件下载.docx(5页珍藏版)》请在冰豆网上搜索。
43:
26
点击:
6799
毕业快一年,做了2个项目,都是在别人的代码上作开发,苦不堪言:
bug实在是太多。
这一年中有大半的时间是在改别人的bug,也积累了一些经验,和大家分享。
我的方法大多数都来自《Windows程序调试》(英文名DebuggingWindowsPrograms)。
那本书里讲了很多方法,我只挑对我自己帮助最大的:
1.
调试内存破坏。
这种bug的表现就是不定时,不定地方的崩溃。
这种bug我一共碰到2次,每一次都花了很长时间,尤其是第二次,花了大家三天时间。
其原因是堆(heap)被破坏掉了。
我的方法是这样的:
在可能出现问题的地方加上对堆的检查,用如下代码:
//Getthecurrentstateoftheflag
//andstoreitinatemporaryvariable
inttmpFlag=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
//TurnOn(OR)-Keepfreedmemoryblocksinthe
//heap’slinkedlistandmarkthemasfreed
tmpFlag|=__CRTDBG_CHECK_ALWAYS_DF;
//Setthenewstatefortheflag
_CrtSetDbgFlag(tmpFlag);
int*nn=newint;
deletenn;
//TurnOff(AND)-prevent_CrtCheckMemoryfrom
//beingcalledateveryallocationrequest,Itwillcausemuchtime
tmpFlag&
=~_CRTDBG_CHECK_ALWAYS_DF;
如果之前堆已经坏掉了,那么程序(Debug版)就会在分配内存的地方中断,在这儿是int*nn=newint;
第一次破坏堆的代码是这样:
typedefstructaa
{
inta;
}AA;
AAs[n];
inti=0;
for(i=0;
i<
n;
i++)
…
for(i=0;
i++){…}
s[i].a=0;
}
内外都使用i做循环变量,就这样把堆破坏了。
第二次的代码比较隐蔽,我先是使用map文件找到了崩溃的地方,但是一看是一个window的API,就放过了,后来还是再用上面的方法,又定位到那个API:
GetFileAttributesEx(szFile,GetFileExInfoStandard,&
attributes);
发现szFile这个参数有问题,是一个不合法的文件名,然后再调用这个API之前作文件名的合法检查,就没事了。
呵呵,真是这个API干的,看来我们还是不能让Microsoft什么都做。
2.查找memoryleak
可以通过内存分配号来查找memoryleak,方法是这样的(我以前写的+msdn,就不翻译了):
YoucanseetheinformationbelowinyourVCoutputwindowiftheapphavememoryleaks
Detectedmemoryleaks!
Dumpingobjects->
{18}normalblockat0x00780E80,64byteslong.
Data:
<
>
CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD
Objectdumpcomplete.
IfyoucannotseethedumpinformationinVC,youcanaddthecodetothefilecrtdbg.h:
#ifdef_DEBUG
#define_CRTDBG_MAP_ALLOC
#define_INC_MALLOC
#include<
stdlib.h>
//customfunctionsdeclaration(ATL+BETAversionproblems)
extern"
C"
void*__cdecl_alloca(size_t);
#definealloca_alloca
#endif
Asyoucansee,_CrtDumpMemoryLeaksgivesyoumuchmoreusefulinformationwhen_CRTDBG_MAP_ALLOCisdefined.Without_CRTDBG_MAP_ALLOCdefined,thedisplayshowsyou:
∙thememoryallocationnumber(insidethecurlybraces).
∙
∙thetypeofblock(normal,client,orCRT).
∙thememorylocationinhexadecimalform.
∙thesizeoftheblockinbytes.
∙thecontentsofthefirst16bytes(alsoinhexadecimal).
∙
Youcanrunyourprogramtwiceinthesameway,thenyoucanfindthatthememoryallocationnumberoftheleakedmemoryisalwaysthesame,soyoucanusethememoryallocationnumbertofindthememoryleak;
directlytosay,youcanbreaktheprogrambymemoryallocationnumber.
ThebelowistakenfromMSDN(DetectingandIsolatingMemoryLeaksUsingMicrosoftVisualC++)
SettingaBreakpointonaMemoryAllocationNumber
Thefilenameandlinenumberinthememoryleakreporttellyouwhereleakedmemoryisallocated,butknowingwherethememoryisallocatedisnotalwayssufficienttoidentifytheproblem.Oftenanallocationwillbecalledmanytimesduringarunoftheprogram,butitmayleakmemoryonlyoncertaincalls.Toidentifytheproblem,youmustknownotonlywheretheleakedmemoryisallocatedbutalsotheconditionsunderwhichtheleakoccurs.Thepieceofinformationthatmakesitpossibleforyoutodothisisthememoryallocationnumber.Thisisthenumberthatappearsincurlybraces,afterthefilenameandlinenumberwhenthosearedisplayed.Forexample,inthefollowingoutput,“18”isthememoryallocationnumber.Itmeanstheleakedmemoryisthe18thblockofmemoryallocatedinyourprogram.
C:
\PROGRAMFILES\VISUALSTUDIO\MyProjects\leaktest\leaktest.cpp(20):
{18}
normalblockat0x00780E80,64byteslong.
TheCRTlibrarycountsallmemoryblocksallocatedduringarunoftheprogram,includingmemoryallocatedbytheCRTlibraryitselforbyotherlibraries,suchasMFC.Therefore,anobjectwithallocationnumbernwillbethenthobjectallocatedinyourprogrambutmaynotbethenthobjectallocatedbyyourcode.(Inmostcases,itwillnotbe.)
Youcanusetheallocationnumbertosetabreakpointatthelocationwherememoryisallocated.Todothis,setalocationbreakpointnearthestartofyourprogram.Whenyourprogrambreaksatthatpoint,youcansetsuchamemoryallocationbreakpointfromtheQuickWatchdialogboxortheWatchwindow.IntheWatchwindow,forexample,typethefollowingexpressionintheNamecolumn:
_crtBreakAlloc
Ifyouareusingthemultithreadeddynamic-linklibrary(DLL)versionoftheCRTlibrary(the/MDoption),youmustincludethecontextoperator,asshownhere:
{,,msvcrtd.dll}_crtBreakAlloc
Now