1.概述在实际的软件开发项目中,程序问题是不可避免的。参加工作后遇到程序的情景我还历历在目。以往的经验告诉我,我们越恐慌,问题就越无解。我们需要先让自己冷静下来,然后再寻找程序问题的解决方案。在Linux下做开发的朋友肯定和core文件打过交道。当他们运行完程序看到内核出现的时候,很多人都惊慌失措,天要塌下来了。事实上,我们不必这样做。只要掌握了用gdb调试核心文件的方法,我们还是可以快速定位程序问题,一举消除bug。更多关于Linux核心文件的内容请阅读这篇文章:http://www.cnblogs.com/dongzhiquan/archive/2012/01/20/2328355.html。本文以实际程序为例,介绍了使用gdb分析core文件的方法和步骤,并演示了常用gdb命令的操作方法。如果想了解更多相关的gdb命令,请自行百度。2.示例程序/****************************************************************************Copyright(C)2015,ZhouZhaoxion.**文件名:GdbDebug.c*文件标识:无*内容概要:Gdb命令演示程序*其他说明:无*当前版本:V1.0*作者:周兆雄*完成日期:20151008*****************************************************************************/#include#include#include//数据类型重定义typedefunsignedcharUINT8;typedefsignedintINT32;typedefunsignedintUINT32;//函数语句voidSleep(UINT32iCountMs);voidPrintInfo(void);INT32main();/**************************************************************************函数说明:主要函数*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期,版本号,修改人,修改内容*----------------------------------------------------------------*20151008V1.0ZhouZhaoxion创建******************************************************************************/INT32main(){PrintInfo();//在屏幕上输出信息nreturn0;}/*************************************************************************函数说明:在屏幕上输出信息*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期版本号修改内容*--------------------------------------------------------------------*20151008V1.0ZhouZhaoxiong创建********************************************************************************/voidPrintInfo(void){UINT32iLoopF??lag=0;UINT32iSum=0;UINT32iLen=0;UINT8*pCtrStr=NULL;iLen=strlen(pCtrStr);for(iLoopF??lag=0;iLoopF??laggdbGdbDebugcore--启动gdb分析core文件GNUgdb(GDB)SUSE(7.3-0.6.1)Copyright(C)2011FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3或更高版本,请参阅:...从/home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...读取符号...完成。Corewasgeneratedby`GdbDebug'.Programterminatedwithsignal11,Segmentationfault.#00x00007f4a736f9812in__strlen_sse2()from/lib64/libc.so.6(gdb)where--检查程序哪里有问题Arrived,问题在GdbDebug.c文件的第64行#20x000000000004005e5inmain()atGdbDebug.c:41(gdb)b41——在GdbDebug中Settingabreakpointonline41ofthe.cfileBreakpoint1at0x4005e0:fileGdbDebug.c,line41.(gdb)b64--Setupabreakpointonline64oftheGdbDebug.cfileBreakpoint2at0x400611:fileGdbDebug.c,line64.(gdb)断点infob--displaythebreakpoint点信息NumTypeDispEnbAddressWhat1breakpointkeepy0x00000000004005e0inmainatGdbDebug.c:412breakpointkeepy0x0000000000400611inPrintInfoatGdbDebug.c:64(gdb)r--运行GdbDebugStartingprogram:/home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebugBreakpoint1,main()atGdbDebug.c:4141PrintInfo();//在屏幕上输出Message(gdb)n--执行下一步Breakpoint2,PrintInfo()atGdbDebug.c:6464iLen=strlen(pCtrStr);(gdb)piLen--打印(输出)iLen$1=0的值(gdb)piLoopF??lag--打印(输出)iLoopF??lag$2=0的值(gdb)c--继续执行Continuing.ProgramreceivedsignalSIGSEGV,Segmentationfault.--程序核心掉落0x00007ffff7ae9812in__strlen_sse2()from/lib64/libc.so.6(gdb)q--退出gdbAdebuggingsessionisactive.Inferior1[process26640]willbekilled.Quitanyway?(yorn)y~/zhouzhaoxiong/zzx/GdbDebug>从上面的分析可以看出,在执行GdbDebug.c文件的第64行时,程序核心丢失了。这时仔细分析程序,发现pCtrStr指针为空。当取一个不存在的指针的长度时,程序会因为找不到地址而崩溃。修改方法也很简单,就是让pCtrStr指针指向具体地址即可。4.常用gdb命令操作示例修改后的代码如下:/*****************************************************************************版权所有(C)2015,周肇雄。**文件名:GdbDebug.c*文件标识:无*内容概要:Gdb命令演示程序*其他说明:无*当前版本:V1.0*作者:周兆雄*完成日期:20151008*****************************************************************************/#include#include#include//数据类型重定义typedefunsignedcharUINT8;typedefsignedintINT32;typedefunsignedintUINT32;//函数语句voidSleep(UINT32iCountMs);voidPrintInfo(void);INT32main();/**************************************************************************函数说明:主要函数*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期,版本号,修改人,修改内容*----------------------------------------------------------------*20151008V1.0ZhouZhaoxion创建******************************************************************************/INT32main(){PrintInfo();//在屏幕上输出信息nreturn0;}/*************************************************************************函数说明:在屏幕上输出信息*输入参数:无*输出参数:无*返回值:无*其他说明:无*修改日期版本号修改内容*--------------------------------------------------------------------*20151008V1.0ZhouZhaoxiong创建********************************************************************************/voidPrintInfo(void){UINT32iLoopF??lag=0;UINT32iSum=0;UINT32iLen=0;UINT8*pCtrStr="hello,world!";//修改了这行代码iLen=strlen(pCtrStr);for(iLoopF??lag=0;iLoopF??laggdbGdbDebug--startgdbdebugging//gnu.org/licenses/gpl.html>Thisisfreesoftware:youarefreetochangeandredistributeit.ThereisNOWARRANTY,totheextentpermittedbylaw.Type"showcopying"and"showwarranty"fordetails.ThisGDBwasconfiguredas"x86_64-suse-linux".Forbugreportinginstructions,please.see:gnu.org/software/gdb/bugs/>...Readingsymbolsfrom/home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...done.(gdb)b64--SetabreakpointBreakpoint1at0x400611atline64oftheGdbDebug.cfile:fileGdbDebug.c,line64.(gdb)b72--在GdbDebug.c文件第72行设立断点Breakpoint2at0x400637:fileGdbDebug.c,line72.(gdb)infob--显示断点信息NumTypeDispEnbAddressWhat1breakpointkeepy0x0000000000400611inPrintInfoatGdbDebug.c:642breakpointkeepy0x0000000000400637inPrintInfoatGdbDebug.c:72(gdb)r--runGdbDebugStartingprogram:/home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebugBreakpoint1,PrintInfo()atGdbDebug.c:6464iLen=strlen(pCtrStr);(gdb)piLen--打印(输出)iLen的值$1=0(gdb)n--执行下一步66for(iLoopF??lag=0;iLoopF??lagLinux下调试C/C++程序必须熟练掌握gdb的用法【本文为专栏作家周兆雄原创文章,作者微信♂:周氏逻辑(logiczhou)】点此阅读作者更多好文