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\n",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