gdb常用命令

一、GDB启动

gdb官方在线帮助文档

编译选项

如果需要使用gdb,在编译代码时需要先将调试开关打开,对应gcc的-g、-g3(提供更多的调试信息)或-ggdb(为gdb提供更多的专有信息)选项,例如:

gcc -g -o test test.c

启动方式

  • 方式一:直接通过命令gdb file加载elf可执行文件

  • 方式二:对于已经在运行的程序,可以先查询对应程序的PID,再通过gdb --pid=XXX动态接入进行调试

启动参数

可以通过执行gdb -h命令查询gdb的启动参数,如:

xiao@DESKTOP-i5:test$ gdb -h
This is the GNU debugger.  Usage:

    gdb [options] [executable-file [core-file or process-id]]
    gdb [options] --args executable-file [inferior-arguments ...]

Selection of debuggee and its files:

  --args             Arguments after executable-file are passed to inferior
  --core=COREFILE    Analyze the core dump COREFILE.
  --exec=EXECFILE    Use EXECFILE as the executable.
  --pid=PID          Attach to running process PID.
  ... ...
  1. 启动文件类参数(Selection of debuggee and its files)

  2. 初始化及命令类参数(Initial commands and command files)

  3. 输出和用户界面类参数(Output and user interface control)

  4. 操作类参数(Operating modes)

  5. 远程调试类参数(Remote debugging options)

  6. 其他参数(Other options)

启动初始化文件

当gdb启动的时候,它会先检查/etc/gdb/gdbinit文件是否存在,如果存在则提取里面的参数并执行。某些场景可以考虑修改该文件,减少每次输入参数的工作量。

二、GDB命令

进GDB后执行help指令,会列出当前版本支持的所有命令类,如果想看该类命令更详细的信息,比如breakpoints类,可以执行help breakpoints进行详细查看,比如:

(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) help breakpoints
Making program stop at certain points.
List of commands:
awatch -- Set a watchpoint for an expression
break -- Set breakpoint at specified location
break-range -- Set a breakpoint for an address range
catch -- Set catchpoints to catch events
... ...

以下按照命令类别进行介绍

断点设置

break [function]
在某函数的进入点设中断点。C++中可以使用class::function或function(type,type)格式来指定函数名。

break filename:function
给指定文件内的某个函数设置断点

break +offset | -offset
当程序停止时,在停止位置的前/后第offset行设中断点

break linenum
指定行号设中断点

break filename:linenum
在某source file的第几行或指定函数设定中断点

break
在下一个要执行的指令设中断点

break [args] if [cond]
当[cond]这个运算式为真,设定中断点。 args可能是上列的任一种情形。

tbreak args
只会生效一次的中断点

rbreak regex
使用正则运算来找寻可能的函数,并在其进入点设中断点。EX:(gdb) rbreak . 这样每个函数开头都有中断点了

break *address
在程序运行的内存地址设置断点

info break [n]
查看断点,n表示断点号

条件断点

只有break和watch支持设置条件断点,比如

break {function} if val == XX
当变量val值等于XX时触发function断点

break {filename.c:line_number} if val == XX
当变量val值等于XX时触发位置断点

rwatch {var} if val != xx
当变量val值不等于XX时触发读断点

如果断点已经存在,则也可以通过condition指令设置断点:

condition bnum expression
修改断点号为bnum的停止条件为expression。比如condition 1 val==xx

condition bnum
清除断点号为bnum的停止条件。

还有一个比较特殊的维护命令ignore,你可以指定程序运行时,忽略停止条件几次。

ignore bnum count
表示忽略断点号为bnum的停止条件count次。

断点控制

delete
删除断点(通过断点编号)

clear
删除断点(通过行号或函数名,也可以通过*addr的方式)

disable
禁止断点

enable
使能断点

设置观测点(watch)

观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:

watch expr
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。

rwatch expr
当表达式(变量)expr被读时,停住程序。

awatch(aw) expr
当表达式(变量)的值被读或被写时,停住程序。

info watchpoints
列出当前所设置了的所有观察点。

注意:当程序执行完成后,所有watch观测点都会自动删除

为断点设置指令

可以设置断点触发后,让gdb自动运行一段指令,格式:

commands [break_num]
... command-list ...
end

当程序被该断点停住时,gdb会依次运行命令列表中的命令。

恢复运行和单步调试

continue(c)
继续执行直到下一个中断点或结束

step(s) [num]
单步跟踪一步多多步,如果有函数调用,它会进入该函数。如果执行set step-mode on,则默认为stepi模式

stepi(si) [num]
执行一条汇编级别指令,会进入函数

next(n) [num]
同样单步跟踪,如果有函数调用,他不会进入该函数

nexti(ni) [num]
执行一条汇编级别指令,不会进入函数

finish
运行程序,直到当前函数返回

until(u)
如果当前在一个循环里执行,则一直执行到循环退出

修改变量值

p v=value

set var v=value

强制函数返回

return 或 return val

强制调用函数

call function

p function

查看当前栈信息

backtrace (bt) [n | -n]
打印当前的函数调用栈的所有信息(n或-n表明只打印栈顶n层或栈底n层)

bt full
查看栈内所有函数的局部变量信息

frame (f)
查看当前栈层信息,包括栈层,函数名,函数值等

info frame(f)
打印出更为详细的当前栈层的信息

frame (f) n
切换栈,n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

frame (f) addr
Select the frame at address addr.

up n
表示向栈的上面移动n层,可以不打n,表示向上移动一层。

down n
表示向栈的下面移动n层,可以不打n,表示向下移动一层。

info args
打印出当前函数的参数名及其值。Print the arguments of the selected frame, each ona separate line.

info locals
打印出当前函数中所有局部变量及其值。

info catch
打印出当前的函数中的异常处理信息。

查看寄存器

info registers
查看寄存器的情况。(除了浮点寄存器)

info all-registers
查看所有寄存器的情况。(包括浮点寄存器)

info registers regname ...
查看指定的寄存器的情况

GDB内部固定4个标准寄存器定义,可以通过$xx的方式访问,分别是:

  • pc:PC指针
  • sp:指向当前栈的位置
  • fp:指向当前的stack frame
  • ps:处理器状态

查看源代码

list linenum
显示程序第linenum行的周围的源程序。

list function
显示函数名为function的函数的源程序。

list
显示当前行后面的源程序。

list -
显示当前行前面的源程序。一般是打印当前行的上5行和下5行,如果显示函数是是上2行下8行,默认是10行。

set listsize count
一次显示的行号,默认10行

show listsize
查看当前listsize的设置。

list first,last
显示从first行到last行之间的代码

list ,last
显示从当前行到last行之间的源代码。

list first,
显示从first行到当前行之间的源代码

disassemble function
查看指定函数的反汇编

disassemble /m function
将汇编和代码关联打印出来

directory(dir) dir_name
指定源文件路径,如果要指定多个路径,windows下用;Linux下用:

show directories
查看当前定义了的文件搜索路径

查看数据

  • 查看连续地址或数组空间,可以用数组名称@个数,比如*pstArrayName@10查看结构体10个数组长度的值

  • 打印数组缺省是不打印下标的,可以通过set print array-indexes on命令使下标打印出来

  • 如果局部变量和全局变量重名,则在局部变量的作用范围内,执行p命令查看到的是局部变量的值,如果想看全局变量的值,则需要p ::全局变量的方式

  • 如果想查看其它函数的局部变量值,可以通过p /参数 函数名::变量名的方式,但前提是这个变量在栈当中。也可以通过frame命令切换到指定函数后直接p。具体参数详见下面描述。

  • 使用examine命令(简写x)查看内存,语法为x /nfu addr
    n:默认为1,标识从addr开始显示内存的长度
    f:显示的格式,比如x、d、c等,具体为:
    x(hex):按十六进制格式显示变量
    d(decimal):按十进制格式显示变量
    u(unsigned decimal):按十进制格式显示无符号整型
    o(octal):按八进制格式显示变量
    t(binary):按二进制格式显示变量
    a(address):按地址格式显示变量
    c(char):按字符格式显示变量
    f(float):按附件数格式显示变量
    i(instruction):按指令格式查看一段地址,p指令不支持,指定的地址要指向一段代码空间
    s(string):按指令格式查看一段地址,p指令不支持
    u:默认为w。u参数可以用下面的字符来代替,b(Bytes)表示单字节,h(Halfwords)表示双字节,w(Words)表示四字节,g(Giant word)表示八字节。

  • display 当程序停住时,或是在你单步跟踪时,这些变量会自动显示。比如可以通过display /i $pc跟踪每一步执行汇编指令。

  • 删除跟踪项可以用undisplaydelete display,禁止使能可以用disable displayenable display
    display expr
    display /fmt expr
    display /fmt addr
    跟踪显示指定的变量或地址

whatis {var}
查看变量类型

ptype {var}
查看var对应的详细类型信息

历史记录

每个print都会被GDB记录下来,以$1、$2、$3 ...这样的方式记录下来,可以使用这个编号访问之前的表达式,比如p $9

GDB环境变量

你可以在GDB的调试环境中定义自己的变量,用来保存一些调试程序中的运行数据。要定义一个GDB的变量很简单只需使用GDB的set命令。GDB的环境变量和UNIX一样,也是以foo = *object_ptr`
使用环境变量时,GDB会在你第一次使用时创建这个变量,而在以后的使用中,则直接对其賦值。环境变量没有类型,你可以给环境变量定义任一的类型。包括结构体和数组。

show convenience
该命令查看当前所设置的所有的环境变量。

这是一个比较强大的功能,环境变量和程序变量的交互使用,将使得程序调试更为灵活便捷。例如:

set $i = 0
print bar[$i++]->contents

于是,当你就不必,print bar[0]->contents, print bar[1]->contents地输入命令了。
输入这样的命令后,只用敲回车,重复执行上一条语句,环境变量会自动累加,从而完成逐个输出的功能。

常用选项

show language
查看当前的语言环境。如果GDB不能识别为你所调试的编程语言,那么默认设置为C语言。

info frame
查看当前函数的程序语言

info source
查看当前文件的程序语言

set print array on
set print array off
show print array
打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的。

set print elements
这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。

show print elements
查看print elements的选项信息。

set print null-stop
如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。

set print pretty on
如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。

set print sevenbit-strings
设置字符显示,是否按“\nnn”的格式显示,如果打开,则字符串或字符数据按\nnn显示,如“\065”。

show print sevenbit-strings
查看字符显示开关是否打开。

set print union
show print union
设置显示结构体时,是否显式其内的联合体数据。

你可能感兴趣的:(gdb常用命令)