进入gdb

首先gdb一般都是用来调试c或c++的,gdb是要运行可执行文件的,所以先要进行编译。具体命令如下:

gcc -g 源文件.c -o 输出的目标文件

-g是用来插入编译所需的信息, -o是用来生成可执行文件

生成的时候会产生一大堆信息,如果不想看的话可以使用 -q 选项,如果想永久设定可以在bashrc中设置别名 alias gdb = ‘gdb -q’

执行

名称 用途 简写
start 进入main函数
run 重新开始运行 run-text 加载文本文件 run-bin加载二进制文件 r
next 执行一行程序,不进入函数,直接把函数执行完 n
step 执行一行程序,进入函数 s
list 查看程序,list+函数名查看函数 l
continue 继续执行到断点处 c
quit 终止程序 q
set 参数 设置断点
nexti 运行一条机器指令 ni
jump + 标号 跳转到某一位置执行 j
run < input.txt 重定向

注意jump命令跳转后仍是一直执行,所以要在某一位置手动设置断点

程序

名称 用途 简写
return 退出函数且不执行后面代码,也可以return+参数指定返回值
finish 退出函数且执行完剩下的代码
call/print 直接调用函数执行
info files 显示所有程序及位置
info functions(regex) 显示函数(可加正则表达式)
set step-mode on 进入不带调试信息的函数(如printf)
set args val1 val2… 设置函数参数

设置断点

名称 用途 简写
break 设置断点 b
tbreak 设置临时断点(只能使用一次) tb
info breakpoints 查看当前所有断点 i b
enable/disable breakpoints 启用/禁用断点
clear+编号 删除断点
break参数
*+地址 在某一地址设置断点 b *0x400522
函数名 在某一函数进入前停止 b main
行号 在某一行号处设置断点 b 7
+offset/-offset 在当前行前后offset行设置
break … if < condition> 只有在条件满足时,断点才会被触发 b 10 if i==101
ignore bnum count 忽略bnum次编号为count的断点 ignore 1 5
观察点 观察变量值的变化
watch 当一个值发生变化时,程序会停下来,相当于是写观察点
reatch 当一个值发生读行为时,程序停止
awatch 每次读取或改变a的值都会让程序停下来 aw
info watch 显示观察点 i watch
catchpoint 当程序异常终止或加载链接库时停止运行,这里不展开
1)设置catchpoints:
a. catch event: 当事件event发生的时候,程序停止运行,这里event的取值有:

1)throw: C++抛出异常
2)catch: C++捕捉到异常
3)exec: exec被调用
4)fork: fork被调用
5)vfork: vfork被调用
6)load: 加载动态库
7)load libname: 加载名为libname的动态库
8)unload: 卸载动态库
9)unload libname: 卸载名为libname的动态库
10)syscall [args]: 调用系统调用,args可以指定系统调用号,或者系统名称
b. tcatch event: 设置只停一次的catchpoint,第一次生效后,该catchpoint被自动删除

这一段从网上扒的

反汇编

disassemble 如果不带参数,会自动显示后面若干条汇编指令。简写disas

如果带一个参数,可以带函数名也可以带某一个地址,都是显示那个地址处的函数的汇编代码。

如果带两个参数,也就是起始地址和终止地址,那么就会显示两个之间的代码

回退

名称 用途 简写
reverse-continue 反向运行程序知道遇到一个能使程序中断的事件(比如断点,观察点,异常)
reverse-step 返回到上一次执行的源代码行
reverse-stepi 返回上一条机器指令
reverse-next 返回上一次执行的源代码行,但不执行函数
reverse-nexti 反向运行到上一条机器指令,除非这条指令用来返回一个函数调用、整个函数将会被反向执行。
reverse-finish 反向运行程序回到调用当前函数的地方

注意,想使用回退功能先要用record命令对指令进行录制

调试带参数的程序

方法1: gdb启动时候加参数

gdb —args ./main aaaa bb

方法2:

gdb main //先启动起来

(gdb)run aaaa bb

方法3

gdb main //先启动起来

(gdb)set args aaaa bb

(gdb)run //或者start

(gdb)show args

这部分照搬的

打印

名称 用途 简写
函数栈帧打印
i frame 输出了当前函数堆栈帧的地址,指令寄存器的值,局部变量地址及值等信息
frame n 打印第n层的函数栈帧
up/down n 向上/向下切换栈帧
print + 数组名 打印数组内容 p
set print array-indexes on 打印数组时打印下标
info locals 打印局部变量值 i locals
backtrace full n 由内向外显示n个栈帧的值 bt
set print pretty on 打印结构体
p *array@len array数组名 len 数据长度
p $寄存器名 查看某个寄存器的值
info register 查看所有寄存器 i reg

x 显示内存中内容命令

格式: x /nfu

n表示要显示的内存单元的个数

f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节