gdb是gnu下的一个调试器,内置的大量的用于调试程序的指令,使用$gdb
进入程序再使用file exe_name
导入要调试的可执行文件或直接使用$gdb exe_name
断点相关
|
|
break 行号/函数名 |
在指定行号或函数处设置断点,程序每次执行到断点处就会停止| |
tbreak 行号/函数名 |
在指定行号或函数处设置临时断点,程序会在到达临时断点处暂停一次 |
break 文件名:行号 |
在指定的文件中的行号处设置断点 |
break <0x...> |
在内存的某一个位置处设置断点 |
break 行号 if 条件 |
满足条件就设置断点,多用于调试循环 |
info b/watchpoint |
查看断点或监视点处的信息 |
clear 行号 |
清除行号的所有断点 |
delete 编号 |
删除指定编号的断点 |
disable 编号 |
使指定编号的断点失效,多个编号之间用空格隔开 |
enable 编号 |
|
awatch/watch 变量 |
设置观察点,当变量被读出或写入时程序被暂停 |
rwatch 变量 |
设置观察点,当变量被程序读时暂停程序 |
数据相关
|
|
display 表达式 |
每当程序运行到断点处都会显示表达式的值 |
info display |
类似info b,显示当前所有要显示值的表达式的相关情况 |
delete display编号 |
删除一个要显示值的表达式 |
disable display编号 |
使一个表达式暂时无效 |
enable display编号 |
|
undisplay display编号 |
用于结束某个表达式的值的显示 |
whatis 变量 |
显示某个表达式的数据类型 |
print 变量/表达式 |
用于打印变量或表达式的值 |
set 变量=值 |
改变程序中一个变量的值 |
环境相关
|
|
set args |
设置运行参数 |
show args |
显示运行参数 |
set width 宽度 |
设置gdb的行宽 |
cd 工作目录 |
切换工作目录 |
run |
执行程序 |
s(step) |
单步,会进入到调用的函数中 |
n(next) |
单步,不会进入到调用的函数中 |
finish |
一直运行到函数返回 |
until 行数 |
运行到函数的某一行 |
c(continue) |
执行到下一个断点或程序结束 |
return 返回值 |
改变程序流程,直接结束到当前函数,并将指定值返回 |
call 函数 |
在当前位置设置所要运行的函数 |
堆栈相关
|
|
bt(backtrace) |
打印栈帧指针,也可以在该命令后加上要打印的指针个数 |
frame |
打印栈帧 |
info reg |
查看寄存器使用情况 |
info stack |
查看堆栈情况 |
up |
跳到上一层函数 |
down |
|
例子
//main.c
#include<stdio.h>
#include"add.h"
int main(int argc, const char *argv[])
{
int i=0;
int num=100;
int res=0;
for(i=1;i<=10;i++){
res=add(num,i);
}
printf("%d
",res);
return 0;
}
//add.c
#include"add.h"
int add(int x, int y){
return x+y;
}
test_gdb $cat add.h
//add.h
#ifndef __ADD_H__
#define __ADD_H__
extern int add(int, int);
#endif //__ADD_H__
(gdb) l
1 #include<stdio.h>
2 #include"add.h"
3 int main(int argc, const char *argv[])
4 {
5 int i=0;
6 int num=100;
7 int res=0;
8 for(i=1;i<=10;i++){
9 res=add(num,i);
10 }
(gdb)
11 printf("%d
",res);
12 return 0;
13 }
(gdb)
Line number 14 out of range; main.c has 13 lines.
(gdb) b add
Breakpoint 1 at 0x8048453: file add.c, line 3.
(gdb) r
Starting program: /home/linux/Desktop/test_gdb/a.out
Breakpoint 1, add (x=100, y=1) at add.c:3
3 return x+y;
(gdb) c
Continuing.
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0x08048423 in main (argc=1, argv=0xbffff2b4) at main.c:9
9 res=add(num,i);
(gdb) c
Continuing.
Breakpoint 1, add (x=100, y=2) at add.c:3
3 return x+y;
...
(gdb) c
Continuing.
Breakpoint 1, add (x=100, y=7) at add.c:3
3 return x+y;
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048453 in add at add.c:3
breakpoint already hit 7 times
(gdb) finish
Run till exit from #0 add (x=100, y=7) at add.c:3
0x08048423 in main (argc=1, argv=0xbffff2b4) at main.c:9
9 res=add(num,i);
Value returned is $1 = 107
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/linux/Desktop/test_gdb/a.out
Breakpoint 1, add (x=100, y=1) at add.c:3
3 return x+y;
(gdb) l #列出当前程序的上下文
1 #include"add.h"
2 int add(int x, int y){
3 return x+y;
4 }
(gdb) l
Line number 5 out of range; add.c has 4 lines.
(gdb) up #跳回到main函数
#1 0x08048423 in main (argc=1, argv=0xbffff2b4) at main.c:9
9 res=add(num,i);
(gdb) watch i #设置i为观察点
Hardware watchpoint 3: i
(gdb) c
Continuing.
Hardware watchpoint 3: i
Old value = 1
New value = 2
0x0804842c in main (argc=1, argv=0xbffff2b4) at main.c:8
8 for(i=1;i<=10;i++){