GDB调用栈调节和测量试验

2019-11-28 07:49栏目:网络技术
TAG:

一起talkGDB吧(第四回:GDB调用栈调试)

各位看官们,大家好,上一回中我们说的是GDB的断点调试功能,并且说了如何使用GDB进行断点调试。

这一回中,我们继续介绍GDB的调试功能:调用栈调试。当然了,我们也会介绍如何使用GDB进行调用栈

调试。闲话休提,言归正转。让我们一起talk GDB吧!

看官们,我们先说一下什么是调用栈。大家都知道,程序中经常使用各种各样的函数,有的是语言提供的

库函数,比如printf(),有的是我们自己定义的函数。各种函数之间会相互调用,有时候函数多了,我们很难

找出函数之间的调用关系,函数栈就是用来显示函数之间调用关系的。这们说大家可能觉得有点抽象,不

容易理解,我们举个例子来说明,例如程序中有以下代码。

void funA()

{

printf("A function is called n");

}

void funB()

{

printf("B function is called n");

funA();

}

void funC()

{

printf("C function is called n");

funB();

}

void funD()

{

printf("D function is called n");

funC();

}

int main()

{

printf("show the call stack of functions n");

funD();

return 0;

}

这些函数的功能比较简单,只有一个输出语句,显示函数被调用。大家可以看到,程序中自己定义了四个

函数,它们分别是:funA,funB,funC,funD。(以后不用全名,简称ABCD)各个函数之间的调用关

系为:D->C->B->A。编译并且运行该函数时,可以得到以下结果:

show the call stack of functions

D function is called

C function is called

B function is called

A function is called

从程序的运行结果中也可以看到,各个函数之间的调用关系。如果把D比作栈底,那么每次调用函数就是

在进行入栈操作,D调用C就是把C入栈,依此类推,直到最后一个函数A。这种函数调用关系符合栈”先进

后出“的特点,因此我们形象地叫它为调用栈。此外,从程序的运行结果中也可以看出来ABCD函数的调用

关系从栈顶到栈底依次排列。

看官们在实际的程序中,函数的功能不会这么简单,函数的调用关系也不会这么简单。如果我们想了解函

数之间的调用关系,怎么办?不用担心,GDB提供了显示函数调用栈的功能。和单步调用一样,调用栈调

试也有专门的命令:backtrace(缩写为bt)。使用该命令,可以通过GDB打印出函数调用栈,我们还是举个

例子来说明,为了方便,还使用上面提到过的代码。

1.首先编译程序,并且加入调试信息:gcc -g file.c -o file

2.启动GDB进行调试:gdb file

3.在函数D处打一个断点:b funD。运行结果如下:Breakpoint 3, funA () at file.c:5

4.运行程序,遇到断点停止运行:run

5.查看函数调用栈:bt.这时显示的结果如下:

(gdb) bt //查看函数调用栈

#0 funA () at file.c:5

#1 0x08048448 in funB () at file.c:10

#2 0x08048461 in funC () at file.c:15

#3 0x0804847a in funD () at file.c:20

#4 0x08048496 in main () at file.c:27

通过运行的结果,我们可以看到,函数A位于栈底,MAIN函数位于栈顶。而且在每行最前面有编号。当然

了,编号从0开始,有点类似数组中元素的位置。

看官们,关于GDB的内容,今天咱们就说到这里。欲知后事如何,且听下回分解!

各位看官们,大家好,上一回中我们说的是GDB的断点调试功能,并且说了如何使用GDB进行断点调试...

版权声明:本文由澳门新葡亰平台游戏发布于网络技术,转载请注明出处:GDB调用栈调节和测量试验