在使用gdb调试时,经常要用到查看堆栈信息,特别是在内核调试时,这

显得尤其重要。通过gdb的堆栈跟踪,可以看到所有已调用的函数列表,以及
每个函数在栈中的信息。
---------------------------------------------------------------------------------
一,简单实例。
  1. #include <stdio.h>


  2. int sum(int m,int n)

  3. {

  4. int i = 3;

  5. int j = 4;

  6.   return m+n;

  7. }


  8. int main(void)

  9. {

  10. int m = 10;

  11. int n = 9;

  12. int ret = 0;


  13.    ret = sum(m,n);


  14.    printf("ret = %d\n",ret);

  15.    return 0;

  16. }

  1. (gdb) bt

  2. #0 sum (m=10, n=9) at sum.c:5

  3. #1 0x08048418 in main () at sum.c:16

每次有函数调用,在栈上就会生成一个栈框(stack frame),也就是一个数据
单元用来描述该函数,描述函数的地址,参数,还有函数的局部变量的值等信息。
使用bt命令就可以把这个栈的调用信息全部显示出来。


由上面的显示结果可以看出,栈上有两个栈框(stack frame),分别用来描述函数
main和函数sum.前面的#0表示sum函数栈框的标号。#1表示main函数栈框的标号。
最新的栈框标号为0.main函数栈框标号最大。
  1. (gdb) frame 1

  2. #1 0x08048418 in main () at sum.c:16

  3. 16 ret = sum(m,n);

frame 1 表示选择栈框1,也就是选择了main函数的栈框,因为我这时候想查看
main函数的信息。

  1. (gdb) info locals

  2. m = 10

  3. n = 9

  4. ret = 0

这时候可以通过info locals查看main函数栈框里面局部变量的值。
-----------------------------------------------------------------------------------
二,使用gdb堆栈跟踪很方面调试递归程序。

  1. #include <stdio.h>


  2. long long func(int n)

  3. {

  4. int i = 0;


  5. if(n > 20){

  6.        printf("n too large!\n");

  7.        return -1;

  8. }

  9. if(n == 0)

  10.        return 1;

  11. else{

  12.        i = n * func(n-1);

  13.        return i;

  14. }

  15. }


  16. int main(void)

  17. {

  18.    long long ret;

  19.    ret = func(10);

  20.    printf("ret = %lld\n",ret);

  21.    return 0;

  22. }

  1. (gdb) bt

  2. #0 func (n=7) at test.c:7

  3. #1 0x0804843f in func (n=8) at test.c:14

  4. #2 0x0804843f in func (n=9) at test.c:14

  5. #3 0x0804843f in func (n=10) at test.c:14

  6. #4 0x08048469 in main () at test.c:22

如上所示,可以很清楚地看到递归深入到了第几层,以及该层局部变量值的情况。