一、 调试前的准备
使用gcc test.c -o test.out
编译时,编译器为了输出执行更快的代码,所以不带有debuginfo,无法使用GDB进行调试,应使用gcc -g test.c -o test.out
进行编译,然后使用gdb ./test.out
进行调试。
二、 调试过程
1. b
指令(b即breakpoint)
b main
:在main函数处打断点
b /home/test.c:13
:在第13行处打断点
b *地址
: 在某地址处打断点
2. 运行调试指令
r
: 运行程序(r即run)
n
: 不进入函数的单步
s
: 进入函数的单步
enter
: 重复上一次的指令
k
: 结束当前调试
clear
: 清楚当前行的断点
info b
: 查看所有断点
d 1
: 删除1号断点
c
: 从当前位置直接运行到下一个断点
bt
: 反过来查看函数的调用顺序backteace
watch i
: 监视变量i,当i的值发生变化时停下(watchpoint),也相当于打断点
info r
: 查看寄存器的值
info variables
: 查看所有变量的值
p $寄存器
: 查看寄存器的值
set var $寄存器 = expr
: 修改寄存器的值
set {type}address=expr
: 给存储在address地址的变量类型为type的变量赋值
i
: 显示信息
3. x
指令(查看内存)
指定大小 起始内存地址,即查看起始内存地址上指定大小的内存里的值。如x /3b 0x11223344
,就是查看以0x11223344
开始的3个字节的值,也可以是x /3w 0x11223344
,就是查看以0x11223344
开始的3个word的值
命令格式:x/<n/f/u> <addr>
n
是一个正整数,表示需要显示的内存单元的个数
f
表示显示的格式(可取如下值: x
按十六进制格式显示变量。d
按十进制格式显示变量。u
按十进制格式显示无符号整型。o
按八进制格式显示变量。t
按二进制格式显示变量。a
按十六进制格式显示变量。i
指令地址格式c
按字符格式显示变量。f
按浮点数格式显示变量。)
u
表示从当前地址往后请求的字节数 默认4byte,u
参数可以用下面的字符来代替,b
表示单字节,h
表示双字节,w
表示四字节,g
表示八字节
<addr>
表示一个内存地址
x/xw addr
显示某个地址处开始的16进制内容,如果有符号表会加载符号表
x/x $esp
查看esp寄存器中的值
如x $ebp-0x2c
x/s addr
查看addr处的字符串
x/b addr
查看addr处的字符
x/i addr
查看addr处的反汇编结果
另外对于int arr[] = {2, 4, 6, 8, 10}
可使用p *arr@3
查看arr数组前三个单元的值