GDB观察栈的内存布局

 进程的内存布局如下图所示,栈是其中一块向下(低地址处)增长的内存。

 栈的英文是stack,堆的英文是heap,很多人把stact翻译成堆栈,是不对的。

              栈由栈帧组成。当一个函数调用时,栈会为这个函数分配一个栈帧,用于存储函数的实参、局部变量、返回值,以及函数内调用函数时,当前函数的一些寄存器的相关信息(比如用于指向下一条指令的程序计数器)。可以认为,一个栈帧存储一个函数。当该函数调用结束后,栈帧会自动从栈上移去(这解释了局部变量的生存期问题)。

由于函数的嵌套,栈中可能有多个栈帧,此时,最后分配的栈帧称为栈顶,如下图所示。栈指针寄存器用于存储栈顶的地址,以跟踪栈顶。

下面,我们使用GDB查看一个实例的栈信息。实例程序gdbtest.cpp如下:

#include <stdio.h>

int square(int a, int b){

    int ret = a*a + b*b;

    return ret;

}

int doCalc(int num1, int num2){

    int ret = square(num1, num2);

    return ret;

}

int main(){

    int param1 = 1;

    int param2 = 2;

    int result = doCalc(param1,param2);

    printf("result is%d\n",result);

}

编译:g++ -g  gdbtest.cpp

启动gdb:gdb  a.out。

             由源文件可知,main函数里面嵌套doCalc函数,doCalc函数又嵌套square函数,因此,这三个函数在栈中的分配如上图所示。在square函数中设置断点,程序停在断点后,使用backtrace命令,即可看到栈内容,如下所示:

(gdb) backtrace

#0  square (a=1, b=2) atgdbtest.cpp:6

#1  0x00000000004005e6 in doCalc(num1=1, num2=2) at gdbtest.cpp:10

#2  0x0000000000400613 in main ()at gdbtest.cpp:17

            每一行前面的序号,就是栈帧在栈中的序号,#0表示栈顶,#1表示下一个栈帧,以此类推。使用frame 1,可以选择1号栈帧,使用info locals可以当前栈帧的局部变量:

(gdb) backtrace

#0 square (a=1, b=2) at gdbtest.cpp:6

#1 0x00000000004005e6 in doCalc (num1=1, num2=2) at gdbtest.cpp:10

#2 0x0000000000400613 in main () at gdbtest.cpp:17

(gdb) frame 1

#1 0x00000000004005e6 in doCalc (num1=1, num2=2) at gdbtest.cpp:10

10       int ret = square(num1, num2);

(gdb) info locals

ret = 0

(gdb)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值