gdb 调试工具:
程序一般出现的错误
编译错误,运行错误,逻辑错误.
gdb 的四方面工作:
1.启动程序,按用户要求影响程序的运行行为
2.使运行程序在指定条件处停止.
3.当程序停止时,检查它出现了什么问题.
4.动态改变程序的执行环境,这样就可以先纠正一个错误,然后再纠正其他错误.
gdb:常用命令
1.为了发挥 gdb 的全部功能,需要在编译源程序时使用 -g 选项,以便在目标代码中加入调试用的各种信息,
如程序的变量名,函数名以及其在源程序中的行号等.
所用格式如下:
$ gcc -g project.c -o project
$ gcc -g project.cpp -o project
在此基础上,可以使用 gdb 对运行失败的程序进行调试.
启动调试的方法:
1.直接使用 shell 命令 gdb:
$ gdb
2.以一个可执行程序作为 gdb 的参数.例如
$ gdb project(可执行文件名相当于 a.out )
3.同时以可执行程序和 core 文件作为 gdb 的参数.例如
$ gdb project(a.out) core
其中, core 文件是直接运行 project 程序造成 core dumped(内存信息传输) 后产生的文件.
4.制定一个进程号 PID 作为 gdb 第二个参数.例如
$ gdb project 1234
其中 1234 是正在进行进程的编号.这样就把 gdb 和该进程绑定在一起.
退出命令: quit
查看帮助信息:
直接用 help command 方式来查看制定的 command 命令帮助信息.如 help paths.
显示源程序和数据:
进入 gdb 之后,在提示符下输入相应的命令可以实现显示,诊断,跟踪等功能.
1.显示搜索源程序:
a.显示源文件(利用 list 命令可以显示源文件中指定的函数或代码行).
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| 格式 | 功能 |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| list | 没有参数,显示当前行之后或周围的 10 多行. |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| list- | 显示当前行之前的 10 行 |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| list[file:] num | 显示源文件 file 中给定行号 num 周围的 10 行.如果缺少 file ,则默认为当前文件.例如, list 100 |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
| list start, end | 显示从行号 start 至 end 之间的代码行.例如 list 20, 38 |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
|list [file:]function|显示源文件 file 中指定函数 function 的代码行.如果缺少 file ,则默认为当前文件.例如 list test.c:square |
+--------------------+-------------------------------------------------------------------------------------------------------------------------------------+
在默认情况下 list 显示的是当前行的上下 5 行.也可以利用 set listsize 命令重新设置一下一次显示源码的行数.
b.模式搜索:
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------------+
| 格式 | 功能 |
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------------+
|forward-search regexp|从列出的最后一行开始向前搜索给定的模式 regexp (即正则表达式,一个字符串的匹配模式).例如 forward-search i = * |
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------------+
| serach regexp | 同上 |
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------------+
|reverse-search regexp|从列出的最后一行开始向后搜索给定的模式 regexp (即正则表达式,一个字符串的匹配模式).例如 reverse-search i = ??|
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------------+
2.查看运行时的数据:
a. printf 命令:查看当前程序运行时数据.其一般使用格式:
print [/fmt] exp
其中 [] 可选,下同; exp 是符合所有编程语言语法规则的表达式.例如,所调试程序是用 C 语言编写的,那么 exp 应是 C 语言合法表达式
fmt 表示输出格式的字母.例如:
print i //显示当前变量 i 的值;
print i * j //将根据当前程序的实际运行情况显示 i * j 的值;
b. gdb 支持的运算符 //
(1). 用 & 去除变量的地址; 一般格式为:例如
print &i; //显示当前变量 i 的地址;
print &array[i] //显示数组 array 第 i 个元素的地址;
(2). {type}adrexp //表示一个数据类型为 type ,存放地址为 adrexp 的数据;
(3). @ 它是一个与数组有关的双目运算符,例如:
print array@10 // 表示打印从 array (数组名,即数组的基地址) 开始的 10 个值;
print array[3]@5 //表示打印从 array 的第三个元素开始的 5 个值;
注意: gdb 发现 array 是数组的基地址,就按照内存地址的方式显示它及它后面的 9 个值.内存地址习惯用 16 进制数表示.
而 array[3] 是第三个元素,以十进制数形式显示它及其后面的四个元素的值.
(4). file :: var 或者 function :: var 表示文件 file (或函数 function)中变量 var 的值.例如:
print inner :: i //表示打印函数 inner 中变量 i 的值.
c. 输出格式:
在 print /fmt exp 命令中 "/" 之后的 fmt 是表示输出格式的字母,它由表示格式的和表示数据长度的字母组成.
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| | 字母 | 作用 | 字母 | 作用 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示格式的字母| o | 八进制格式 | f | 浮点数格式 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示格式的字母| x | 十六进制格式 | a | 地址格式 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示格式的字母| d | 十进制格式 | i | 指令格式 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示格式的字母| u | 无符号十进制格式 | c | 字符格式 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示格式的字母| t | 二进制格式 | s | 字符串格式 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示长度的字母| b | 1 个字节长度 | h | 半个字符串 |
+-----------------------+----------+--------------------------------+-------------+----------------------------+
| 表示长度的字母| w | 1 个整字节长度 | g | 8 个字节长度 |
+-----------------------+----------+--------------------------------+--------------+----------------------------+
d. whatis 命令(显示变量的数据类型) 例如:
(gdb) whatis i
type = int (表示变量 i 是 int 型)
e. x 命令:利用 x 命令可以查看内存地址中数据的值.其一般格式为:
x [/fmt] address //其中 fmt 表示显示格式的字母, 它由表示格式和数据长度的字母组成
address 是表示查看内存地址的表达式
f. display 命令:
g.
3. 改变和显示目录或路径
a. directory 命令:
该命令可以将给定的目录 dir 添加在源文件搜索路径的开头并且忽略先前保存的有关源文件和代码行位置信息.
其一般格式:
directory [dir] 或者 dir [dir] //其中 dir 表示制定的目录它可以是环境变量 $cwd (表示当前工
作目录)或$cdir(表示把源文件编译成目标代码的目录).如果不带参数则默认吧搜索路径重置为%cdir:$cwd,
从而清除用户所有自定义源文件搜索路径信息
b. cd 命令:
将调试程序和被调试程序的工作目录指定为 dir .其一般格式是:
cd dir
c. path 命令:
将一个或者多个目录添加至目标文件搜索路径的开头,其一般格式是
path dir //在路径中可用$cwd 来表示当前工作目录,它等价于shell变量的$PATH .
目录表中各个目录以冒号分开,gdb 搜索这些目录以便找到链接好的可执行文件和所需的分别编译的目标文件
d. pwd 命令:显示工作目录
e. show directory 显示定义的源文件搜索路径
f. show paths 显示当前查找目标文件的搜索路径.
4. 控制程序的执行:
(1).设置和显示观察点
a. 设置断点: break 命令
break linenum (在当前指定文件制定行 linenum, 设置断点,停在该行开头)
break linenum if condition (在当前文件指定行 linenum 设置断点, 仅仅在表达式 condition 成立时才停止执行)
break function (在当前文件函数 function 入口处添加断点)
break file:linenum (在源文件的 file 的 linenum 行上)
break *address (指定内存地址处添加断点)
break (不带参数,表示在下一条命令处添加)
b. 显示断点:
info breakpoints [num]
info break [num] //其中 [num] 表示断点号码,该命令列出所有断点的清单
(2). 设置和显示观察点
a. 设置观察点
watch expr (为表达式 expr 设置观察点,一旦值有变化,马上停止程序)
rwatch expr (当表达式 expr 的值被读取时,就停止程序)