gdb查看堆栈
- 格式:pdf
- 大小:148.97 KB
- 文档页数:8
8ExaminingtheStack查看堆栈
Whenyourprogramhasstopped,thefirstthingyouneedtoknowiswhereitstoppedand
howitgotthere.
当你的程序到暂停到断点处时,你需要知道的第一件事就是知道程序停在哪儿,以及
通过什么样的函数调用关系到达这里的。
Eachtimeyourprogramperformsafunctioncall,informationaboutthecallisgenerated.
Thatinformationincludesthelocationofthecallinyourprogram,theargumentsofthe
call,andthelocalvariablesofthefunctionbeingcalled.Theinformationissavedinablock
ofdatacalledastackframe.Thestackframesareallocatedinaregionofmemorycalled
thecallstack.
每当你的程序调用一个函数,这个函数的相关信息将会生成,这信息包括这个函数在
程序中的位置,函数的参数,以及被调函数局部变量的值。这些信息保存在一个数据
块中,这个数据块叫做栈框。这些栈框位于内存中称为栈的区域。
Whenyourprogramstops,thegdbcommandsforexaminingthestackallowyoutosee
allofthisinformation.
当你的程序断点处停止,gdb查看堆栈的命令允许你看所有函数相关的信息。
Oneofthestackframesisselectedbygdbandmanygdbcommandsreferimplicitly
totheselectedframe.Inparticular,wheneveryouaskgdbforthevalueofavariablein
yourprogram,thevalueisfoundintheselectedframe.Therearespecialgdbcommandsto
selectwhicheverframeyouareinterestedin.SeeSection8.3[SelectingaFrame],page88.
Whenyourprogramstops,gdbautomaticallyselectsthecurrentlyexecutingframeand
describesitbriefly,similartotheframecommand(seeSection8.4[Informationabouta
Frame],page89).
gdb将会选择其中的某个栈框。如果没有明确指出栈框,很多gdb命令也隐含地指出了选择
的栈框。特别是,当你使用gdb查看你程序中某个变量的值时。这个值将会在指定的某个栈
框中找到。这儿有几个gdb命令去选择你感兴趣的栈框。看Section8.3,88页,当程序停止
后,gdb将会自动选择当前执行的栈框。以及简单地描述它。和后面要说的栈框的命令相似
8.1StackFrames(栈框)
Thecallstackisdividedupintocontiguouspiecescalledstackframes,orframesforshort;
eachframeisthedataassociatedwithonecalltoonefunction.Theframecontainsthe
argumentsgiventothefunction,thefunction’slocalvariables,andtheaddressatwhich
thefunctionisexecuting.
栈被划分成多个连续的块,每个块称为栈框,或短框;每个栈框都存有与调用函数相关的数
据。栈框中包含了调用函数的参数,调用函数的局部变量。以及这个函数的执行的地址。
Whenyourprogramisstarted,thestackhasonlyoneframe,thatofthefunctionmain.
Thisiscalledtheinitialframeortheoutermostframe.Eachtimeafunctioniscalled,a
newframeismade.Eachtimeafunctionreturns,theframeforthatfunctioninvocation
iseliminated.Ifafunctionisrecursive,therecanbemanyframesforthesamefunction.
Theframeforthefunctioninwhichexecutionisactuallyoccurringiscalledtheinnermostframe.Thisisthemostrecentlycreatedofallthestackframesthatstillexist.
Insideyourprogram,stackframesareidentifiedbytheiraddresses.Astackframe
consistsofmanybytes,eachofwhichhasitsownaddress;eachkindofcomputerhasa
conventionforchoosingonebytewhoseaddressservesastheaddressoftheframe.Usually
thisaddressiskeptinaregistercalledtheframepointerregister(seeSection10.12[Registers],
page126)whileexecutionisgoingoninthatframe.
当程序开始执行时,栈上就只有一个栈框,也就是用来描述Main函数的。这个栈框称为初
始化栈框或最外层栈框。每当调用一个函数,一个新的栈框将会生成。每当一个函数结束,
该函数对应的栈框将会消除。如果一个函数是递归函数,这将会对同一个函数产生很多个栈
框。正在执行函数的栈框将叫做最内层栈框。这个是所有存在栈框中最新创建的。
在你的程序里,栈框通过它对应到的地址进行标识。一个栈框由多个字节组成,每个栈框都
有自己的地址,当程序执行到这个栈框时。通常这个栈框地址存放在特定的寄存器中(看
Section10.12[Registers],126页),
gdbassignsnumberstoallexistingstackframes,startingwithzerofortheinnermost
frame,onefortheframethatcalledit,andsoonupward.Thesenumbersdonotreally
existinyourprogram;theyareassignedbygdbtogiveyouawayofdesignatingstack
framesingdbcommands.
gdb为每个存在的栈框赋上一个标号。标号从0开始,0表示最里层的栈框。也就是正在被
调用函数的栈框。这些标号在程序中并不存在,它是由gdb赋予的,gdb通过赋予这个标号
来给gdb的命令指定哪个栈框。
Somecompilersprovideawaytocompilefunctionssothattheyoperatewithoutstack
frames.(Forexample,thegccoption‘-fomit-frame-pointer’generatesfunctionswithoutaframe.)
Thisisoccasionallydonewithheavilyusedlibraryfunctionstosavetheframesetuptime.gdbhas
limitedfacilitiesfordealingwith
Debuggingwithgdb
thesefunctioninvocations.Iftheinnermostfunctioninvocationhasnostack
frame,gdb
neverthelessregardsitasthoughithadaseparateframe,whichisnumbered
zeroasusual,
allowingcorrecttracingofthefunctioncallchain.However,gdbhasno
provisionfor
framelessfunctionselsewhereinthestack.
frameargs
Theframecommandallowsyoutomovefromonestackframetoanother,and
toprintthestackframeyouselect.argsmaybeeithertheaddressoftheframe
orthestackframenumber.Withoutanargument,frameprintsthecurrent
stackframe.
这个frame命令允许你从一个栈框移动到另一个栈框,然后可以打印出你选择的栈框,args
要么是栈框的地址,要么是栈框的标号,如果没有参数,frame命令将会打印出当前的栈框。
select-frame
Theselect-framecommandallowsyoutomovefromonestackframetoanotherwithoutprintingtheframe.Thisisthesilentversionofframe.
select-frame命令允许你从一个栈框移动到另外一个栈框而不打印栈框的信息,
这个命令可以看作是frame命令的silent版本。
8.2Backtraces
Abacktraceisasummaryofhowyourprogramgotwhereitis.Itshowsonelineperframe,
formanyframes,startingwiththecurrentlyexecutingframe(framezero),followedbyits
caller(frameone),andonupthestack.
Backtrace命令是查看你程序通过什么样的函数调用关系到达这断点的概括。它将为每个栈
框显示一行。对于多个栈框,从当前执行的那个栈框开始,接下来就是显示调用正在执行函
数的函数的栈框。
backtrace
bt
Printabacktraceoftheentirestack:onelineperframeforallframesinthe
stack.
Bt命令打印栈全部的backtrace,每个栈框显示一行。
Youcanstopthebacktraceatanytimebytypingthesysteminterruptcharac-ter,normallyCtrl-c.
你可以在任何时间结束backtrace通过键入系统中断字符,ctrl+c
backtracen
btn
Similar,butprintonlytheinnermostnframes.
btn命令将会显示最内层的n个栈框。
backtrace-n
bt-n
Similar,butprintonlytheoutermostnframes.
bt-n将会显示最外层的n个栈框。
backtracefull
btfull
btfulln
btfull-n
Printthevaluesofthelocalvariablesalso.nspecifiesthenumberofframesto
print,asdescribedabove.
如果添加full这个参数的话,将会显示栈框中的局部变量。
Thenameswhereandinfostack(abbreviatedinfos)areadditionalaliasesforbacktrace.
Inamulti-threadedprogram,gdbbydefaultshowsthebacktraceonlyforthecurrent
thread.Todisplaythebacktraceforseveralorallofthethreads,usethecommandthread
apply(seeSection4.10[Threads],page35).Forexample,ifyoutypethreadapplyall
backtrace,gdbwilldisplaythebacktraceforallthethreads;thisishandywhenyoudebug
acoredumpofamulti-threadedprogram.Eachlineinthebacktraceshowstheframenumber
andthefunctionname.Theprogramcountervalueisalsoshown—unlessyouusesetprint
addressoff.Thebacktracealsoshowsthesourcefilenameandlinenumber,aswellas
theargumentstothefunction.The
programcountervalueisomittedifitisatthebeginningofthecodeforthatlinenumber.