gdb
什么是gdb
gdb是GNU开源组织发布的一个用于Unix/Linux的程序调试工具。
与其它调试器一样,gdb可以在程序中设置断点、查看变量值,跟踪程序执行的过程。
利用调试器的这些功能可以方便地找出程序中存在的非语法错误。
在用到gdb之前要先在Linux上安装gdb
编写程序用于测试
#include <stdio.h>
int get_sum(int n)
{
int sum=0, i;
for (i=0;i<n;i++)
sum += i;
return sum;
}
int main()
{
int j=100, res;
res = get_sum(j);
printf("1+2+...+%d = %d\n",j,res);
return 0;
}
运行该程序
编译
在命令行模式下输入:gcc -g test.c -o test
注意在用到gdb调试器之前的编译阶段必须要加上参数-g
运行
命令行模式下输入:.\test
。
gdb的启动
第一种启动方式:
gdb [程序名]
gdb test
会有一些证书的说明或是一些其他的东西。
若不想显示这些东西,可以加上参数–quiet
第二种启动方式:
gdb --quiet
(gdb)file test
gdb的退出
(gdb)quit
help
(gdb) help会返回help的一个大类。
(gdb)help files会返回真正的能使用的在help中的files中的命令。
gdb的常用命令
显示程序源代码list
会有一个看不到的光标在记录每一次的list的行数,可以用list n,n来把光标设置在某一行。
list: 输出从上次调用list命令开始向后的10行程序代码(第一次使用时显示中间部分的代码段)
list -: 输出从上次调用list命令处向前10行代码
由于上一次的调用时从4开始调用的。所以这次的list-执行的就是从第三行向前找十行,一直到程序最开始。
list n: 输出n行附近的10行代码
list [函数名]: 输出函数附近的10行代码
list n1,n2: 显示第n1行到n2行的代码
搜索字符串
forward/search [字符串]: 从当前位置向后查找指定的字符串所在的程序行,查找时不包括当前行,可以用list n,n将当前行设置为n
reverse-search [字符串]: 从当前行向前查找第一个匹配的字符串
执行程序
在shell环境下使用gdb test,或在gdb环境下使用file test只是载入了程序,但是程序是没有运行的
运行:
(gdb)run
向指出程序的绝对路径
后执行程序中的打印
最后推出程序。
设置断点
每一个断点都会有一个属于它自己的断点编号。
以行数设置断点
格式: break n //在第n行设置断点
功能: 当程序运行到指定行时,会暂停执行,指定行的代码不执行(第n行的代码并不会执行)。
例如:
(gdb)break 15
(gdb)run
以函数设置断点
格式: break [函数名]
例如:
(gdb)break get_sum
(gdb)run
以条件表达式设置断点
格式: break [行号或函数名] if [条件]
功能: 程序在运行过程中,满足设定条件时,程序在所设置处中断
例如:
(gdb)break 7 if i==99
含义: 当程序执行到第7行时,判断条件i==99是否成立,若成立则中断
以条件表达式变化设置断点
格式: watch [条件表达式]
功能: 程序在运行过程中,当满足设定条件时,程序中断
注意:watch必须在程序运行的过程中设置观察点,即运行run之后,并且要保证条件表达式中的变量已经使用过。
使用watch之前要设置断点,并且要将程序进行运行。
例1
(gdb)break 13
(gdb)run
(gdb)watch sum==3
例2
(gdb)break 5
(gdb)run
(gdb)watch sum==3
此时i和sum仍然是0的原因就是,因为中间有断点,所以不会运行到sum==3的时候,要想让程序运行到观察点,就要将程序继续运行:
gdb的使用
查看断点
查看当前设置的断点
格式: info breakpoints
例如:
(gdb)break 7
(gdb)break 15 if res==5050
(gdb)info breakpoints
keep:可以循环使用
enable:y:生效。n:失效
管理断点
- 使中断失效或有效
失效: disable [断点编号]
有效: enable [断点编号]
- 删除断点
clear [行号]: 删除此行的断点
delete [断点编号]: 删除指定编号的断点, 若有一次删除多个断点,各断点编号以空格分开。
delete: 删除程序中所有的断点
查看和设置变量的值
当程序执行到中断点暂停时,往往需要查看变量或表达式的值,借此了解程序的执行状态,进而发现问题。
功能: 打印变量或表达式的值,还可以用来对某个变量进行赋值。
print [变量或表达式]: 打印变量或表达式的值
print [变量]=[值]: 对变量进行赋值
例如:
(gdb)break 7
(gdb)run
(gdb)print i < n
(gdb)print i
(gdb)print sum
(gdb)print i=200
(gdb)continue
whatis(没有空格)
功能: 用于显示某个变量或表达式的数据类型
格式: whatis [变量或表达式]
例如:
(gdb)break 7
(gdb)run
(gdb)whatis i
(gdb)whatis sum
(gdb)whatis sum+0.5
set
功能: 给变量赋值
格式: set variable [变量]=[值]
控制程序的执行
当程序执行到指定的中断点时,完成相关的debug操作后,可以让程序继续运行
1 continue
程序继续运行,直到下一个断点或运行完毕
2 kill
结束当前程序的调试
3 next/step
功能: 一次一条执行程序代码
区别: next把函数调用当做一条语句来执行;step追踪进入函数,一次一条地执行内部代码。