﻿# 第十一部分：GDB 调试器

# GDB 调试器

The gnu project debugger

1、监视程序中变量的值  
2、在程序中设置断点  
3、程序性的单步执行

Gcc 编译的时候需要添加选项-g -ggdb

调试符号插入到生成的二进制代码

默认不加入调试符号信息

可执行文件大小会增加

调试信息分级-g1/-g2/-g3

-g2 默认扩展到符号表、行号、局部或外部变量的信息  
-g3 包含级别 2 中的所有调试信息以及源代码中的宏  
-g1 不包含局部变量和与行号有关的调试信息，因此只能用回溯跟踪和堆栈转储

回溯追踪：指的是监视程序在运行过程中函数调用历史。

堆栈转储：以原始的十六进制格式保存程序的执行环境。

任何调试选项都会急剧增大生成的二进制文件的大小，同时增加执行的开销，因此，通常仅用于开发和调试。

使用 gdb filename 启动 gdb，其中 filename 应为可执行文件

```txt
Gdba .out 
```

```txt
Gdb 常用命令
```

R命令 使用命令r运行程序

如果在同一调试过程中需要多次运行程序(run)，后续再执行时便可直接使用 r 指令，系统会默认使用之前的参数。

进行调试过程中重新编译程序后，不必退出 gdb，使用 r 指令重新运行程序，gdb 会自动更新程序状态。

List（I）命令

用来列出源文件中的部分源代码。（需要编译时加入

-g选项生成对应的编译符号）

l source_file_name.c:col （l 源文件名：行号）

l function_name，以函数为整体进行输出

断点 b

和继续执行c命令

Disable /enable 来停用/启用编号为 n 的断点

命令b可以在需要地方放置断点，程序在断点位置停止运行

格式：b 断点位置

其中，断点位置可以是行号，也可以是函数名(指定方式与l 指令类似)，也可以是地址。

使用 c 命令从断点继续执行后续指令。使用命令 disable/enable 断点号 可以启用/停用某断点。使用指令 d 可删除所有的断点，d 1 删除 breakpoint 1.

```txt
b 10 //在源代码10行处放置断点  
b main //在main函数开始处放置断点  
b *0x80480000 //在存放在0x80480000处的指令处放置断点，直接使用地址时需要使用 *地址 的格式  
b 10 if a<10 //可以在断点中加入中断执行的条件，表示当a < 10时才会中断程序执行
```

Watch 。

```txt
watch a //当变量a的值发生变化时，中断程序执行  
watch -1 a // watch指令指定了-1参数时，会将指令所接的表达式的计算结果作为地址，//观察该地址处的值的变化情况  
rwatch a //当a的值被读取时，中断表达式的执行
```

可以为某一表达式设置观察点，当程序执行过程中表达式的值发生改变时，gdb 会中断程序执行，并显示表达式的变化情况

Disp 显示 打印命令 p

P 打印命令

disp(display)命令可以在每次程序暂停时显示指定变量的值

格式：disp 变量名

若输入的变量为数组名，则每次显示数组的所有元素，若为结构体，则输出结构体的所有成员的值。

p(print)命令也将变量的值打印出来，用法与 diap 类似，但结果只显示一次。

除变量外，p 命令还可以输出给定寄存器、给定地址处的值。

通过一些参数对打印格式进行规定，如 /x 表示以16进制格式打印值，/t表示以二进制格式打印值。

其它显示类 info 命令  
```txt
info reg //输出所有寄存器的当前值  
info frame //输出栈帧的使用情况  
info b n //其中n为指定的断点号，显示指定断点的状态信息，//不加参数n时，会显示所有的断点的信息  
内存检查 examine
```

命令

X fmt address

x 命令用于检查内存中某一区域的值，

格式：x fmt address

其中 address 为内存地址的表达式，fmt 由 /重复次数 $\cdot ^ { + }$ 格式化字符 $^ +$ 尺寸字符 组成。

格式化字符有 o(octal，八进制)，x(hex，十六进制)， d(decimal，十进制)，u(unsigneddecimal，无符号十进 制 )，t(binary，二进 制)，f(float，浮点)，a(address，地址)，i(instruction ， 指 令 ) ， c(char ， 字 符 ) ， s(string ， 字 符 串 ). 尺 寸 字 符 有b(byte)，h(halfword)， w(word)， g(giant, 8 bytes)

执行（s 与 n）命令

回溯（bt）命令

设置（set）指令

### 执行（s 与 n）命令

s与n指令都是表示执行下一条指令指令的意思  
s指令会进入函数调用内部进行执行，即下一步为被调函数的第一指令。  
n指令不进入函数调用内部，会将整个函数的执行过程当作一步执行。

### 回溯（bt）命令

回溯指令(backtrace)可以查看程序内存访问越界等错误信息，显示程序出错的位置，从而帮助定位程序错误。

### 设置（set）指令

设置指令set可以将指定的变量的值修改为调试所需要的值。如对于一个int型的变量X，可以使用setX=12将变量的值进行设置。

可以使用宏定义对一些常用指令进行定义。

格式 ：define 宏名，并根据提示输入宏定义，以 end 作为结尾标志。
