gdb查看堆栈
- 格式:pdf
- 大小:148.97 KB
- 文档页数:8
8Examining the Stack查看堆栈
When your program has stopped,the first thing you need to know is where it stopped and
how it got there.
当你的程序到暂停到断点处时,你需要知道的第一件事就是知道程序停在哪儿,以及
通过什么样的函数调用关系到达这里的。
Each time your program performs a function call,information about the call is generated.
That information includes the location of the call in your program,the arguments of the
call,and the local variables of the function being called.The information is saved in a block
of data called a stack frame.The stack frames are allocated in a region of memory called
the call stack.
每当你的程序调用一个函数,这个函数的相关信息将会生成,这信息包括这个函数在
程序中的位置,函数的参数,以及被调函数局部变量的值。
这些信息保存在一个数据
块中,这个数据块叫做栈框。
这些栈框位于内存中称为栈的区域。
When your program stops,the gdb commands for examining the stack allow you to see
all of this information.
当你的程序断点处停止,gdb查看堆栈的命令允许你看所有函数相关的信息。
One of the stack frames is selected by gdb and many gdb commands refer implicitly
to the selected frame.In particular,whenever you ask gdb for the value of a variable in
your program,the value is found in the selected frame.There are special gdb commands to
select whichever frame you are interested in.See Section8.3[Selecting a Frame],page88.
When your program stops,gdb automatically selects the currently executing frame and describes it briefly,similar to the frame command(see Section8.4[Information about a Frame],page89).
gdb将会选择其中的某个栈框。
如果没有明确指出栈框,很多gdb命令也隐含地指出了选择的栈框。
特别是,当你使用gdb查看你程序中某个变量的值时。
这个值将会在指定的某个栈框中找到。
这儿有几个gdb命令去选择你感兴趣的栈框。
看Section8.3,88页,当程序停止后,gdb将会自动选择当前执行的栈框。
以及简单地描述它。
和后面要说的栈框的命令相似
8.1Stack Frames(栈框)
The call stack is divided up into contiguous pieces called stack frames,or frames for short;
each frame is the data associated with one call to one function.The frame contains the arguments given to the function,the function’s local variables,and the address at which
the function is executing.
栈被划分成多个连续的块,每个块称为栈框,或短框;每个栈框都存有与调用函数相关的数据。
栈框中包含了调用函数的参数,调用函数的局部变量。
以及这个函数的执行的地址。
When your program is started,the stack has only one frame,that of the function main.
This is called the initial frame or the outermost frame.Each time a function is called,a
new frame is made.Each time a function returns,the frame for that function invocation
is eliminated.If a function is recursive,there can be many frames for the same function.
The frame for the function in which execution is actually occurring is called the innermost
frame.This is the most recently created of all the stack frames that still exist.
Inside your program,stack frames are identified by their addresses.A stack frame
consists of many bytes,each of which has its own address;each kind of computer has a convention for choosing one byte whose address serves as the address of the ually
this address is kept in a register called the frame pointer register(see Section10.12[Registers], page126)while execution is going on in that frame.
当程序开始执行时,栈上就只有一个栈框,也就是用来描述Main函数的。
这个栈框称为初始化栈框或最外层栈框。
每当调用一个函数,一个新的栈框将会生成。
每当一个函数结束,该函数对应的栈框将会消除。
如果一个函数是递归函数,这将会对同一个函数产生很多个栈框。
正在执行函数的栈框将叫做最内层栈框。
这个是所有存在栈框中最新创建的。
在你的程序里,栈框通过它对应到的地址进行标识。
一个栈框由多个字节组成,每个栈框都有自己的地址,当程序执行到这个栈框时。
通常这个栈框地址存放在特定的寄存器中(看Section10.12[Registers],126页),
gdb assigns numbers to all existing stack frames,starting with zero for the innermost
frame,one for the frame that called it,and so on upward.These numbers do not really
exist in your program;they are assigned by gdb to give you a way of designating stack
frames in gdb commands.
gdb为每个存在的栈框赋上一个标号。
标号从0开始,0表示最里层的栈框。
也就是正在被调用函数的栈框。
这些标号在程序中并不存在,它是由gdb赋予的,gdb通过赋予这个标号来给gdb的命令指定哪个栈框。
Some compilers provide a way to compile functions so that they operate without stack
frames.(For example,the gcc option‘-fomit-frame-pointer’generates functions without a frame.) This is occasionally done with heavily used library functions to save the frame setup time.gdb has limited facilities for dealing with
Debugging with gdb
these function invocations.If the innermost function invocation has no stack
frame,gdb
nevertheless regards it as though it had a separate frame,which is numbered
zero as usual,
allowing correct tracing of the function call chain.However,gdb has no
provision for
frameless functions elsewhere in the stack.
frame args
The frame command allows you to move from one stack frame to another,and
to print the stack frame you select.args may be either the address of the frame
or the stack frame number.Without an argument,frame prints the current
stack frame.
这个frame命令允许你从一个栈框移动到另一个栈框,然后可以打印出你选择的栈框,args 要么是栈框的地址,要么是栈框的标号,如果没有参数,frame命令将会打印出当前的栈框。
select-frame
The select-frame command allows you to move from one stack frame to another without printing
the frame.This is the silent version of frame.
select-frame命令允许你从一个栈框移动到另外一个栈框而不打印栈框的信息,
这个命令可以看作是frame命令的silent版本。
8.2Backtraces
A backtrace is a summary of how your program got where it is.It shows one line per frame,
for many frames,starting with the currently executing frame(frame zero),followed by its
caller(frame one),and on up the stack.
Backtrace命令是查看你程序通过什么样的函数调用关系到达这断点的概括。
它将为每个栈框显示一行。
对于多个栈框,从当前执行的那个栈框开始,接下来就是显示调用正在执行函数的函数的栈框。
backtrace
bt
Print a backtrace of the entire stack:one line per frame for all frames in the
stack.
Bt命令打印栈全部的backtrace,每个栈框显示一行。
You can stop the backtrace at any time by typing the system interrupt charac-ter,normally Ctrl-c.你可以在任何时间结束backtrace通过键入系统中断字符,ctrl+c
backtrace n
bt n
Similar,but print only the innermost n frames.
bt n命令将会显示最内层的n个栈框。
backtrace-n
bt-n
Similar,but print only the outermost n frames.
bt-n将会显示最外层的n个栈框。
backtrace full
bt full
bt full n
bt full-n
Print the values of the local variables also.n specifies the number of frames to
print,as described above.
如果添加full这个参数的话,将会显示栈框中的局部变量。
The names where and info stack(abbreviated info s)are additional aliases for backtrace.
In a multi-threaded program,gdb by default shows the backtrace only for the current
thread.To display the backtrace for several or all of the threads,use the command thread
apply(see Section4.10[Threads],page35).For example,if you type thread apply all backtrace,gdb will display the backtrace for all the threads;this is handy when you debug
a core dump of a multi-threaded program.Each line in the backtrace shows the frame number
and the function name.The program counter value is also shown—unless you use set print address off.The backtrace also shows the source file name and line number,as well as
the arguments to the function.The
program counter value is omitted if it is at the beginning of the code for that line number.
Here is an example of a backtrace.It was made with the command‘bt3’,so it
shows
the innermost three frames.
这儿是一个backtrace的例子。
如下的显示是通过执行bt3生成的,所以显示的是最内层的3个栈框。
#0
m4_traceon(obs=0x24eb0,argc=1,argv=0x2b8c8)
at builtin.c:993
#10x6e38in expand_macro(sym=0x2b600,data=...)at macro.c:242
#20x6840in expand_token(obs=0x0,t=177664,td=0xf7fffb08)
at macro.c:71
(More stack frames follow...)
The display for frame zero does not begin with a program counter value,indicating that
your program has stopped at the beginning of the code for line993of builtin.c.
The value of parameter data in frame1has been replaced by....By default,gdb prints
the value of a parameter only if it is a scalar(integer,pointer,enumeration,etc).See
command set print frame-arguments in Section10.8[Print Settings],page113for more
details on how to configure the way function parameter values are printed.
If your program was compiled with optimizations,some compilers will optimize away arguments passed to functions if those arguments are never used after the call.Such optimizations generate code that passes arguments through registers,but doesn’t store those arguments in the stack frame.gdb has no way of displaying such arguments in stack frames
other than the innermost one.Here’s what such a backtrace might look like:
#0
m4_traceon(obs=0x24eb0,argc=1,argv=0x2b8c8)
at builtin.c:993
#10x6e38in expand_macro(sym=<optimized out>)at macro.c:242
#20x6840in expand_token(obs=0x0,t=<optimized out>,td=0xf7fffb08)
at macro.c:71
(More stack frames follow...)
The values of arguments that were not saved in their stack frames are shown
as‘<optimized
out>’.
If you need to display the values of such optimized-out arguments,either
deduce that
from other variables whose values depend on the one you are interested in,or
recompile
without optimizations.
Most programs have a standard user entry point—a place where system
libraries and
startup code transition into user code.For C this is main1.When gdb finds
the entry
function in a backtrace it will terminate the backtrace,to avoid tracing into
highly system-
specific(and generally uninteresting)code.
If you need to examine the startup code,or limit the number of levels in a
backtrace,
you can change this behavior:
set backtrace past-main
set backtrace past-main on
Backtraces will continue past the user entry point.
set backtrace past-main off
Backtraces will stop when they encounter the user entry point.This is the
default.
show backtrace past-main
Display the current user entry point backtrace policy.
1
Note that embedded programs(the so-called“free-standing”environment)are
not required to have a
main function as the entry point.They could even have multiple entry points.
88
Debugging with gdb
set backtrace past-entry
set backtrace past-entry on
Backtraces will continue past the internal entry point of an application.This
entry point is encoded by the linker when the application is built,and is likely
before the user entry point main(or equivalent)is called.
set backtrace past-entry off
Backtraces will stop when they encounter the internal entry point of an appli-
cation.This is the default.
show backtrace past-entry
Display the current internal entry point backtrace policy.
set backtrace limit n
set backtrace limit0
Limit the backtrace to n levels.A value of zero means unlimited.
show backtrace limit
Display the current limit on backtrace levels.
8.3Selecting a Frame选择某个栈框
Most commands for examining the stack and other data in your program work on whichever stack frame is selected at the moment.Here are the commands for selecting a stack frame;
all of them finish by printing a brief description of the stack frame just selected.
很多gdb为查看堆栈和里面的数据提供了很多子命令,这儿就有选择栈框的一些命令。
frame n
fn
Select frame number n.Recall that frame zero is the innermost(currently
executing)frame,frame one is the frame that called the innermost one,and so
on.The highest-numbered frame is the one for main.
frame n(fn)将会选择栈框n,栈框0是最内层的栈框,也就是当前执行的函数,栈框1
是调用最内层栈框的函数。
最大的栈框就是main函数对应的栈框。
frame addr
f addr
Select the frame at address addr.This is useful mainly if the chaining of stack
frames has been damaged by a bug,making it impossible for gdb to assign
numbers properly to all frames.In addition,this can be useful when your
program has multiple stacks and switches between them.
通过栈框的地址选择栈框。
如果栈框被bug破坏掉了,这将是主要的方法去查看栈框。
栈框破坏掉了,gdb将不能通过栈框标号去定位栈框。
另外,如果你的程序有多个栈,在多个栈切换时这中方法将很有用。
On the SPARC architecture,frame needs two addresses to select an arbitrary
frame:a frame pointer and a stack pointer.
On the MIPS and Alpha architecture,it needs two addresses:a stack pointer
and a program counter.
On the29k architecture,it needs three addresses:a register stack pointer,a
program counter,and a memory stack pointer.
up n Move n frames up the stack.For positive numbers n,this advances
toward the outermost frame,to higher frame numbers,to frames that have existed
Longer.n defaults to one.
up n将会朝外层栈框走n个。
它的方向是朝最外层的栈框,也就是最大的栈框号
down n Move n frames down the stack.For positive numbers n,this advances
toward the innermost frame,to lower frame numbers,to frames that were created
more recently.n defaults to one.You may abbreviate down as do.
down n和up n是对应的,它将会朝最内层走n个栈框。
All of these commands end by printing two lines of output describing the
frame.The first line shows the frame number,the function name,the arguments,and the
source file and line number of execution in that frame.The second line shows the text of
that source line.
这些命令将会打印两行关于该栈框的信息,第一行将会显示栈框号,函数名,参数,以及源代码所在的文件名,和所在的行。
For example:
(gdb)up
#10x22f0in main(argc=1,argv=0xf7fffbf4,env=0xf7fffbfc)
at env.c:10
10
read_input_file(argv[i]);
After such a printout,the list command with no arguments prints ten lines
centered on
the point of execution in the frame.You can also edit the program at the point
of execution
with your favorite editing program by typing edit.See Section9.1[Printing Source Lines],
page91,for details.
up-silently n
down-silently n
These two commands are variants of up and down,respectively;they differ in that they do their work silently,without causing display of the new frame. They
are intended primarily for use in gdb command scripts,where the output might
be unnecessary and distracting.
8.4Information About a Frame
There are several other commands to print information about the selected stack frame.
frame
f
When used without any argument,this command does not change which frame
is selected,but prints a brief description of the currently selected stack frame. It can be abbreviated f.With an argument,this command is used to select a stack frame.See Section8.3[Selecting a Frame],page88.
info frame
info f
This command prints a verbose description of the selected stack frame,includ-ing:
•the address of the frame
•the address of the next frame down(called by this frame)
•the address of the next frame up(caller of this frame)
•the language in which the source code corresponding to this frame is written •the address of the frame’s arguments
•the address of the frame’s local variables
•the program counter saved in it(the address of execution in the caller frame)
•which registers were saved in the frame
The verbose description is useful when something has gone wrong that has made
the stack format fail to fit the usual conventions.
Debugging with gdb
info frame addr
info f addr
Print a verbose description of the frame at address addr,without selecting
that
frame.The selected frame remains unchanged by this command.This requires
the same kind of address(more than one for some architectures)that you specify
in the frame command.See Section8.3[Selecting a Frame],page88.
info args Print the arguments of the selected frame,each on a separate line. info locals
Print the local variables of the selected frame,each on a separate line.These are all variables(declared either static or automatic)accessible at the point of execution of the selected frame.。