6.5 KiB
GDB 的使用
1.基本指令
# Attach 到已运行的进程
(gdb) attach <pid>
# 设置调试目标文件(解决找不到符号或找不到文件问题)
(gdb) file <debug targe file>
# 开启/关闭伪图形窗口
(gdb) tui enable/disable
# 设置参数
(gdb) r <arg 1> <arg 2> ...
# 查看各级函数调用及参数
(gdb) backtrace
(gdb) bt
# 切换调用栈
(gdb) f <n>
# 退出 gdb 调试环境
(gdb) quit
(gdb) q
2.断点
# location 可以为:linenum,filename:linenum,+offset,-offset,function,filename:function
(gdb) break <location>
(gdb) b <location>
# 删除断点
(gdb) delete [breakpoints num] [range...]
(gdb) d [breakpoints num] [range...]
# 查看断点信息(breakpoints num)
(gdb) info breakpoints
(gdb) info b
# 禁用断点
(gdb) dis <breakpoints num>
# 清除全部断点
(gdb) clear
# 删除所选定的环境中所有的断点
(gdb) clear <location>
3.执行控制
# 运行程序
(gdb) run
(gdb) r
# 停止后继续执行程序
(gdb) c
# step into line
(gdb) step
(gdb) s
# step over line
(gdb) next
(gdb) n
# step into instruction
(gdb) stepi
# step over instruction
(gdb) nexti
# 连续运行到当前函数返回为止,然后停下来等待命令
(gdb) finish
4.变量查看
4.1.Print
print 的功能就是在 GDB 调试程序的过程中,输出或者修改指定变量或者表达式的值。
# 标准格式
print [options --] [/fmt] expr
# 显示变量的值
(gdb) p <variable>
# 修改变量的值
(gdb) p <variable>=<value>
# 显示结构体变量成员内容,使用 set print pretty on 可使结构体成员的显示更友好
(gdb) p <struct obj>
(gdb) p *<struct ptr>
其中 options 可以为下列值:
Options | Description |
---|---|
-address on/off | 查看某一指针变量的值时,是否同时打印其占用的内存地址,默认值为 on。该选项等同于单独执行 set print address on/off 命令。 |
-array on/off | 是否以便于阅读的格式输出数组中的元素,默认值为 off。该选项等同于单独执行 set printf array on/off 命令。 |
-array-indexes on/off | 对于非字符类型数组,在打印数组中每个元素值的同时,是否同时显示每个元素对应的数组下标,默认值为 off。该选项等同于单独执行 set print array-indexes on/off 命令。 |
-pretty on/off | 以便于阅读的格式打印某个结构体变量的值,默认值为 off。该选项等同于单独执行 set print pretty on/off 命令。 |
注意,options 参数和 /fmt 或者 expr 之间,必须用--( 2 个 - 字符)分隔。
expr 表示要查看的目标变量或表达式;参数 fmt 用于指定输出变量或表达式的格式,如下表:
/fmt | Functions |
---|---|
/x | 以十六进制的形式打印出整数。 |
/d | 以有符号、十进制的形式打印出整数。 |
/u | 以无符号、十进制的形式打印出整数。 |
/o | 以八进制的形式打印出整数。 |
/t | 以二进制的形式打印出整数。 |
/f | 以浮点数的形式打印变量或表达式的值。 |
/c | 以字符形式打印变量或表达式的值。 |
当 print 命令不指定任何 options 参数时,print 和 /fmt 之间不用添加空格。
print 命令可以打印指定变量或表达式的值。值得一提的是,当指定目标表达式时,除了表达式本身外,GDB 调试器还支持使用@和::运算符。
@运算符用于输出数组中指定区域的元素,使用格式如下:
(gdb) print <first>@<len>
当程序中包含多个作用域不同但名称相同的变量或表达式时,可以借助::运算符明确指定要查看的目标变量或表达式。::运算符的语法格式如下:
(gdb) print <file>::<variable>
(gdb) print <function>::<variable>
4.2.Display
和 print 命令一样,display 命令也用于调试阶段查看某个变量或表达式的值,它们的区别是,使用 display 命令查看变量或表达式的值,每当程序暂停执行(例如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。
(gdb) display expr
(gdb) display/fmt expr
fmt 和 expr 的解释同 print。
事实上,对于使用 display 命令查看的目标变量或表达式,都会被记录在一张列表(称为自动显示列表)中。通过执行info dispaly命令,可以打印出这张表:
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
2: y /t result
1: y num
其中,各列的含义为:
- Num 列为各变量或表达式的编号,GDB 调试器为每个变量或表达式都分配有唯一的编号;
- Enb 列表示当前各个变量(表达式)是处于激活状态还是禁用状态,如果处于激活状态(用 y 表示),则每次程序停止执行,该变量的值都会被打印出来;反之,如果处于禁用状态(用 n 表示),则该变量(表达式)的值不会被打印。
- Expression 列:表示查看的变量或表达式。
对于不需要再打印值的变量或表达式,可以将其删除或者禁用:
# 删除自动显示列表中的变量或表达式
(gdb) undisplay <num...>
(gdb) delete display <num...>
# 禁用自动显示列表中处于激活状态下的变量或表达式
disable display <num...>
# 当然根据需要,也可以激活当前处于禁用状态的变量或表达式
enable display <num...>
参数 num... 表示目标变量或表达式的编号,编号的个数可以是多个。
5.察看寄存器
# 查看所有寄存器的情况(包括浮点寄存器)
(gdb) info registers
# 查看寄存器的情况(除了浮点寄存器)
(gdb) info all-registers
# 查看所指定的寄存器的情况
(gdb) p $<regname>
# 比如
(gdb) p $eip
6.Info
# 查看当前栈帧局部变量的值
(gdb) info locals
(gdb) i locals
# 查看当前设置的所有断点信息
(gdb) info breakpoints
# 查看线程信息
(gdb) info threads
7.查看内存命令
使用 examine 命令,字母缩写为 x 查看内存地址的值。x 命令语法:
x/[number][format] <addr>
number: 一个正整数,表示从当前地址向后显示几个地址的内容; format:显示的格式设置,与 print 的 fmt 参数一致; addr:为查看变量的内存地址。