您的位置:首页 > 运维架构 > Linux

Linux下gdb调试程序之堆栈跟踪

2015-08-31 17:01 323 查看
在使用gdb调试时,经常要用到查看堆栈信息,特别是在内核调试时,这

显得尤其重要。通过gdb的堆栈跟踪,可以看到所有已调用的函数列表,以及

每个函数在栈中的信息。

---------------------------------------------------------------------------------

一,简单实例。

#include <stdio.h>

int sum(int m,int n)

{

int i = 3;

int j = 4;

return m+n;

}

int main(void)

{

int m = 10;

int n = 9;

int ret = 0;

ret = sum(m,n);

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

return 0;

}

(gdb) bt

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

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

每次有函数调用,在栈上就会生成一个栈框(stack frame),也就是一个数据

单元用来描述该函数,描述函数的地址,参数,还有函数的局部变量的值等信息。

使用bt命令就可以把这个栈的调用信息全部显示出来。

由上面的显示结果可以看出,栈上有两个栈框(stack frame),分别用来描述函数

main和函数sum.前面的#0表示sum函数栈框的标号。#1表示main函数栈框的标号。

最新的栈框标号为0.main函数栈框标号最大。

(gdb) frame 1

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

16 ret = sum(m,n);

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

main函数的信息。

(gdb) info locals

m = 10

n = 9

ret = 0

这时候可以通过info locals查看main函数栈框里面局部变量的值。

-----------------------------------------------------------------------------------

二,使用gdb堆栈跟踪很方面调试递归程序。

#include <stdio.h>

long long func(int n)

{

int i = 0;

if (n > 20) {

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

return -1;

}

if (n == 0)

return 1;

else {

i = n * func(n-1);

return i;

}

}

int main(void)

{

long long ret;

ret = func(10);

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

return 0;

}

(gdb) bt

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

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

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

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

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

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

参考:http://www.ibm.com/developerworks/cn/linux/sdk/gdb/index.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: