GDB不完全手册巫山霏云使用GDB调试程序必须在被调试程序中间加入调试信息,FreePascal和GCC都是使用的–g选项,在命令行下使用如下方法:fpc–gtemp.pas这样编译出来的程序就带有编译信息咯,可以直接被GDB认出来。p.s.fpc的编译选项中文解释我已经在DRS,OIBH上面公布了,有兴趣的可以去看看,也可以去我的Website查找。在FP的IDE中可以在Option菜单下的mode中间选择Debug模式,然后编译程序,即可使编译后的程序带有调试信息。需要说明的是没人情况下直接按F9编译出来的程序并没有带调试信息,但是当你按F7调试程序时,FP会重新按照编译模式编译一次代码,从而使你可以编译程序。直接使用GDB有两种形式,一种从IDE里面的DeBug菜单中GDBWindow进入GDB界面。这样可以直接使用GDB,但是仍然不是很稳定。我不是特别推荐,当然这个也有好处,和IDE结合比较紧密。比较好的方法是在命令行下面输入gdbtemp.exe直接进入GDB,如下:D:\fpc\bin\win32\fpc.exe–gE:\prodata\program\temp\temp.pasFreePascalCompilerversion2.0.2[2005/12/27]fori386Copyright(c)1993-2005byFlorianKlaempflTargetOS:Win32fori386CompilingE:\prodata\program\temp\temp.pasLinkingE:\prodata\program\temp\temp.exe99Linescompiled,0.1secD:\fpc\bin\win32\gdb.exeE:\prodata\program\temp\temp.exeGNUgdb6.2.1Copyright2004FreeSoftwareFoundation,Inc.GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouarewelcometochangeitand/ordistributecopiesofitundercertainconditions.Typeshowcopyingtoseetheconditions.ThereisabsolutelynowarrantyforGDB.Typeshowwarrantyfordetails.ThisGDBwasconfiguredasi686-pc-cygwin...(gdb)这样便进入了GDB调试环境。当然你也可以进入GDB后用file再装入要调试的程序:(gdb)filetemp.exeReadingsymbolsfrom/cygdrive/e/prodata/program/temp/temp.exe...done.退出呢?quit拉,缩写就是q拉。小心别随便输入哦,不然你设置的断点监视什么的就没有咯,下次就会比较麻烦的咯。(gdb)是提示符,你也可以更改的,使用setpromptuserdefine厄,我比较喜欢GDB:(gdb)setpromptGDBGDB我们可以设置成我们喜欢的提示符,这样看起来更加好看些。进入后你可以查看当前的语言,GDB能够自动识别你所用的编程语言,当然也有可能不能识别,这时你可以设置一下:GDBshowlanguageThecurrentsourcelanguageisauto;currentlypascal.GDBsetlanguagepascalGDBshowlanguageThecurrentsourcelanguageispascal.GDBsetlanguagecGDBshowlanguageThecurrentsourcelanguageisc.GDBsetlanguagepascalGDBshowlanguageThecurrentsourcelanguageispascal.GDB能够自动的识别命令的缩写,这意味着我们可以不必输入冗长的代码,而只需输入部分缩写,例如list可以缩写成l,break可以缩写成b,这样的简写还有很多。你可以在GDB中尝试输入,如果GDB不能自动识别,也会给出所有的可能,然后让你选择。List指令是列出代码的意思:GDBlist1{2ID:bethune13LANG:PASCAL4PROG:beads5}6Var7dat:Array[1..350]OfChar;8fin,fout:Text;9count,zoo:Word;10GDBl11ProcedureInit;12Var13i:Word;14Begin15Assign(fin,'beads.in');16Reset(fin);17Readln(fin,count);18FillChar(dat,sizeof(dat),#0);19Fori:=1TocountDoRead(fin,dat[i]);20Close(fin);List默认列出10行代码,你也可以指定列出哪10行,用listn,这样n上下5行都会列出来,list–则显示上次显示的10行的上面的10行,具体看下面的例子:GDBl57ko:Boolean;58i:Word;59Begin60ko:=True;61Fori:=1TocountDo62Ifdat[i]'b'Thenko:=False;63IfkoThenExit(True);64ko:=True;65Fori:=1TocountDo66Ifdat[i]'w'Thenko:=False;GDBl67IfkoThenExit(True);68ko:=True;69Fori:=1TocountDo70Ifdat[i]'r'Thenko:=False;71same:=ko;72End;7374Proceduremain;75Var76i,tmp:Word;GDBl-57ko:Boolean;58i:Word;59Begin60ko:=True;61Fori:=1TocountDo62Ifdat[i]'b'Thenko:=False;63IfkoThenExit(True);64ko:=True;65Fori:=1TocountDo66Ifdat[i]'w'Thenko:=False;Run命令可以让程序运行,可以简写为r。不过我们是来调试的,当然不要直接运行拉,调试就少不了断点,断点使用b即break来设置,用法是b行号,譬如b12,如果没有行号就是在当前设置断点,这个在进入栈调试时很有用。也可以设置在进入某一个函数时停止,如bfind,注意:主程序的断点名称是main,和C里面的一样的名字!Break也有高级应用,如可以条件判断Break…ifcondition例如:breakifx=1当x=1时,程序会自动暂停!Breakfindifi=5当find函数中的i=5时,程序会自动暂停。我设置了断点如何查看呢?使用infobreak就会列出所有的断点详细信息:GDBb62Breakpoint1at$4012c4:filetemp.pas,line62.GDBbmainBreakpoint2at$40149c:filetemp.pas,line97.GDBinfobNumTypeDispEnbAddressWhat1breakpointkeepy$004012c4inSAMEattemp.pas:622breakpointkeepy$0040149cinmainattemp.pas:97设置了断点我停是停下来咯,可是我还要继续运行程序啊!当然,我们可以使用c即continue来继续运行程序。厄,设置错误了怎么办?退出重新来呗!嘿嘿,当然不要那么麻烦拉!Del即可!用法:deln(n为断点号)。那如果我要暂时使某个断点不可用怎么办啊?disablen(n为断点号)enablen就是恢复断点的使用拉!GDBdisable1GDBinfobNumTypeDispEnbAddressWhat1breakpointkeepn$004012c4inSAMEattemp.pas:622breakpointkeepy$0040149cinmainattemp.pas:97GDBenable1GDBinfobNumTypeDispEnbAddressWhat1breakpointkeepy$004012c4inSAMEattemp.pas:622breakpointkeepy$0040149cinmainattemp.pas:97GDBdel1GDBinfobNumTypeDispEnbAddressWhat2breakpointkeepy$0040149cinmainattemp.pas:97厄,断点我是知道使用了,可是只有断点也没有用啊!我又不能查看变量的值,怎么弄啊。呵呵,这个当然要有的拉printx(x为变量名称)。我们先启动程序:GDBRStartingprogram:/cygdrive/e/prodata/program/temp/temp.exeBreakpoint2,main()attemp.pas:9797Init;厄,还得补充点知识,我们在FPIDE中间按F7,F8,时是步进,GDB中F7是什么指令呢?Step!即sn(n表示前进几步)F8是n即next,大家自己试试吧。和S一样的属性哦。GDBsINIT()attemp.pas:1515Assign(fin,'beads.in');GDBs16Reset(fin);GDBs17Readln(fin,count);GDBprintcount$1=0GDBs18FillChar(dat,sizeof(dat),#0);GDBprintcount$2=29GDBl13i:Word;14Begin15Assign(fin,'beads.in');16Reset(fin);17Readln(fin,count);18FillChar(dat,sizeof(dat),#0);19Fori:=1TocountDoRead(fin,dat[i]);20Close(fin);21End;22GDBn19Fori:=1TocountDoRead(fin,dat[i]);GDBn20Close(fin);GDBn21End;GDBnmain()attemp.pas:9898main;Print使用还是很方便的,我们可以用来输出一个表达式的值,并输出下一行的代码。与P类似的是echo,大家可以输入helpecho了解。另外有个output只输出值,而不输出下一行代码,而且不把打印的值记录在历史中间。Display可以设置一些自动显示的变量,当程序停住时,或是在但不跟踪时,这些变量会自动显示,用法:DisplayexprExpr为一个表达式。如果进入一个函数了,我想直接退出怎么办啊,老在里面转很晕呢,OK,没有问题,你可以使用u即until来返回,它将运行到函数返回,除非中间还有别的断点。可是我想用IDE中间的Watch功能呢,厄….当然还是watch拉,而且远比IDE中间的功能强大!Watchexpexp为表达式,我们可以简单的就只要监视变量的值的改变就有咯。而且,当你的程序运行时,倘若监视的变量的值发生了改变,程序会自动暂停下来,并输出值和下一行代码。这样你可以很方便的查看咯!怎么样,比IDE中间的功能强大吧,GDBwatchiHardwarewatchpoint3:IGDBwatchcountHardwarewatchpoint4:COUNTGDBinfowatchNumTypeDispEnbAddressWhat1breakpointkeepy$004012c4inSAMEattemp.pas:62breakpointalreadyhit1time2breakpoin