NotePublic/Software/Applications/GDB/GDB_的使用.md

6.5 KiB
Raw Blame History

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为查看变量的内存地址。

8.外部参考资料

  1. GDB调试教程1小时玩转Linux gdb命令