# GDB 的使用 ## 1.基本指令 ```bash # 设置调试目标文件(解决找不到符号或找不到文件问题) (gdb) file # 开启/关闭伪图形窗口 (gdb) tui enable/disable # 设置参数 (gdb) r ... # 查看各级函数调用及参数 (gdb) backtrace (gdb) bt # 切换调用栈 (gdb) f # 退出 gdb 调试环境 (gdb) quit (gdb) q ``` ## 2.断点 ```bash # location 可以为:linenum,filename:linenum,+offset,-offset,function,filename:function (gdb) break (gdb) b # 删除断点 (gdb) delete [breakpoints num] [range...] (gdb) d [breakpoints num] [range...] # 查看断点信息(breakpoints num) (gdb) info breakpoints (gdb) info b # 禁用断点 (gdb) dis # 清除全部断点 (gdb) clear # 删除所选定的环境中所有的断点 (gdb) clear ``` ## 3.执行控制 ```bash # 运行程序 (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 调试程序的过程中,输出或者修改指定变量或者表达式的值。 ```bash # 标准格式 print [options --] [/fmt] expr # 显示变量的值 (gdb) p # 修改变量的值 (gdb) p = # 显示结构体变量成员内容,使用 set print pretty on 可使结构体成员的显示更友好 (gdb) p (gdb) p * ``` 其中 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 调试器还支持使用@和::运算符。 @运算符用于输出数组中指定区域的元素,使用格式如下: ```bash (gdb) print @ ``` 当程序中包含多个作用域不同但名称相同的变量或表达式时,可以借助::运算符明确指定要查看的目标变量或表达式。::运算符的语法格式如下: ```bash (gdb) print :: (gdb) print :: ``` ### 4.2.Display 和 print 命令一样,display 命令也用于调试阶段查看某个变量或表达式的值,它们的区别是,使用 display 命令查看变量或表达式的值,每当程序暂停执行(例如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。 ```bash (gdb) display expr (gdb) display/fmt expr ``` fmt 和 expr 的解释同 print。 事实上,对于使用 display 命令查看的目标变量或表达式,都会被记录在一张列表(称为自动显示列表)中。通过执行info dispaly命令,可以打印出这张表: ```bash (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 列:表示查看的变量或表达式。 对于不需要再打印值的变量或表达式,可以将其删除或者禁用: ```bash # 删除自动显示列表中的变量或表达式 (gdb) undisplay (gdb) delete display # 禁用自动显示列表中处于激活状态下的变量或表达式 disable display # 当然根据需要,也可以激活当前处于禁用状态的变量或表达式 enable display ``` 参数 num... 表示目标变量或表达式的编号,编号的个数可以是多个。 ## 5.察看寄存器 ```bash # 查看所有寄存器的情况(包括浮点寄存器) (gdb) info registers # 查看寄存器的情况(除了浮点寄存器) (gdb) info all-registers # 查看所指定的寄存器的情况 (gdb) p $ # 比如 (gdb) p $eip ``` ## 6.Info ```bash # 查看当前栈帧局部变量的值 (gdb) info locals (gdb) i locals # 查看当前设置的所有断点信息 (gdb) info breakpoints # 查看线程信息 (gdb) info threads ``` ## 7.查看内存命令 使用 examine 命令,字母缩写为 x 查看内存地址的值。x 命令语法: ```bash x/[number][format] ``` number: 一个正整数,表示从当前地址向后显示几个地址的内容; format:显示的格式设置,与 print 的 fmt 参数一致; addr:为查看变量的内存地址。 ## 8.外部参考资料 1. [GDB调试教程:1小时玩转Linux gdb命令](http://c.biancheng.net/gdb/)