backtrace:查看函数的调用顺序(函数调用栈的信息)
frame N (实际上是上下文跳转的命令):切换到栈编号为N的上下文中
info frame:查看当前函数调用的栈帧信息。所谓栈帧就是与函数调用相关的栈上的消息
什么是栈帧信息
深入info命令
命令 功能说明
info registers 查看当前寄存器的值
info args 查看当前函数参数的值
info locals 查看当前局部变量的值
info frame 查看当前栈帧的详细信息
info variables 查看程序中的变量符号
info functions 查看程序中的函数符号
示例:函数调用栈的查看
#include <stdio.h>
int sum(int n)
{
int ret =0;
if(n > 0)
{
ret = n += sum(n-1);
}
return ret;
}
int main()
{
int s=0;
s = sum(10);
printf("sum = %d
",s);
return 0;
}
调试过程如下:
gdb
(gdb) file test.out
(gdb) start
(gdb) break sun if n==0
(gdb) continue
(gdb) backtrace //此时就会显示函数调用的顺序
如果此时面对的是开源代码,想知道我们感兴趣的函数是如何调用的,可以通过backtrace
给我们的启示:当分析不太熟悉的代码时,gdb是一个很好的助手。
(gdb) next
(gdb) next
(gdb) info args //将会打印0
(gdb) frame 7 //切换到编号为7的栈帧所对应的函数调用上下文中去了
(gdb) info args //将会打印7
(gdb) info locals //打印局部变量的值
(gdb) frame 0
(gdb) info registers 打印寄存器的值
(gdb) info frame
一些调试中的小技巧
操作 命令
端点处自动打印 display /f expression display设置断点的自动打印
undisplay
查看程序中的符号 whatis
所对应的信息 ptype
GDB中的代码查看 list
set listsize N
GDB中的shell操作 shell
技巧示例:断点处自动打印
(gdb) shell gcc -g test.c -o test.out
(gdb) file test.out
(gdb) start
(gdb) break test.c : 18
(gdb) continue
(gdb) display / d i
(gdb) display / d i*i
(gdb) display / a &i
每次断点被触发,i,i*i,i的地址就会被打印出来
技巧示例:符号查看
(gdb) whatis func
type = int() 函数类型
(gdb) ptype func
type = int()
(gdb) whatis g_var
type = int
(gdb) ptype g_var
type = int
(gdb) whatis struct ST
type = struct ST
(gdb) ptype struct ST
type = struct ST{
int i;
int j;
};
示例2:
gdb
(gdb) shell cat test.c
或
(gdb) shell gedit test.c
(gdb) shell gcc -g test.c -o test.out
(gdb) file test.out
(gdb) start
(gdb) break test.c:18
(gdb) list test.c : 18 //如果不知道test.c的第18行是什么,可以用list来查看
(gdb) set listsize 20 设置显示代码的行数,每次显示20行
(gdb) show listsize 看看设置有没有成功
(gdb) list test.c : 18
(gdb) continue
//每次程序执行到这个断点时,下面我们感兴趣的值就会被打印出来
(gdb) display /d i
(gdb) display /d i*i
(gdb) display / a &i
(gdb) continue