gdb
简介
GDB(GNU Debugger)是GCC的调试工具。使用编译器(cc/gcc/g++)的 -g 参数生成调试信息: gcc -g hello.c -o hello g++ -g hello.cpp -o hello 如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。
启动GDB
1、gdb program 2、gdb program core 用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。 3、gdb PID process-id 指定这个服务程序运行时的进程ID,gdb会自动attach
下面是一些最常用的GDB命令:
file [filename] 装入想要调试的可执行文件
kill [filename] 终止正在调试的程序
b [file:]function 在(file文件的)function函数中设置一个断点
clear 删除一个断点,这个命令需要指定代码行或者函数名作为参数
run [arglist] 运行您的程序 (如果指定了arglist,则将arglist作为参数运行程序)
bt Backtrace: 显示程序堆栈信息
print expr 打印表达式的值
continue 继续运行您的程序 (在停止之后,比如在一个断点之后)
list 列出产生执行文件的源代码的一部分
next 单步执行 (在停止之后); 跳过函数调用
nexti 执行下一行的源代码中的一条汇编指令
set 设置变量的值。例如:set nval=54 将把54保存到nval变量中
step 单步执行 (在停止之后); 进入函数调用
stepi 继续执行程序下一行源代码中的汇编指令。如果是函数调用,这个命令将进入函数的内部,单步执行函数中的汇编代码
watch 使你能监视一个变量的值而不管它何时被改变
rwatch 指定一个变量,如果这个变量被读,则暂停程序运行,在调试器中显示信息,并等待下一个调试命令。参考rwatch和watch命令
awatch 指定一个变量,如果这个变量被读或者被写,则暂停程序运行,在调试器中显示信息,并等待下一个调试命令。参考rwatch和watch命令
Ctrl-C 在当前位置停止执行正在执行的程序,断点在当前行
disable 禁止断点功能,这个命令需要禁止的断点在断点列表索引值作为参数
display 在断点的停止的地方,显示指定的表达式的值。(显示变量)
undisplay 删除一个display设置的变量显示。这个命令需要将display list中的索引做参数
enable 允许断点功能,这个命令需要允许的断点在断点列表索引值作为参数
finish 继续执行,直到当前函数返回
ignore 忽略某个断点制定的次数。例:ignore 4 23 忽略断点4的23次运行,在第24次的时候中断
info [name] 查看name信息
load 动态载入一个可执行文件到调试器
xbreak 在当前函数的退出的点上设置一个断点
whatis 显示变量的值和类型
ptype 显示变量的类型
return 强制从当前函数返回
txbreak 在当前函数的退出的点上设置一个临时的断点(只可使用一次)
make 使你能不退出 gdb 就可以重新产生可执行文件
shell 使你能不离开 gdb 就执行 UNIX shell 命令
help [name] 显示GDB命令的信息,或者显示如何使用GDB的总体信息
quit 退出gdb
程序运行上下文
set args 可指定运行时参数。(如:set args 10 20 30 40 50 )
show args 命令可以查看设置好的运行参数。
run (r) 不带参数启动程序
r 10 20 30 40 50 指定运行参数
cd 相当于shell的cd命令。
pwd 显示当前的所在目录。
info terminal显示你程序用到的终端的模式,使用重定向控制程序输出。如:run > outfile
设置断点
简单断点
break 设置断点,可以简写为b
b 10设置断点,在源程序第10行
b func设置断点,在func函数入口处
b filename:linenum 在源文件filename的linenum行处停住
b filename:function 在源文件filename的function函数的入口处停住
b class::function或function(type,type) 在类class的function函数的入口处停住
b namespace::class::function 在名称空间为namespace的类class的function函数的入口处停住
b linespec thread threadno 线程断点
b linespec thread threadno if …
查询所有断点
info b
观察点
watch 为表达式(变量)expr设置一个观察点。当表达式值有变化时,停住程序。
rwatch表达式(变量)expr被读时,停住程序。
awatch 表达式(变量)的值被读或被写时,停住程序。
info watchpoints列出当前所设置了的所有观察点。
条件断点
b test.c:8 if intValue == 5
condition bnum expression 修改断点号为bnum的停止条件为expression
condition bnum 清除断点号为bnum的停止条件
ignore bnum count 表示忽略断点号为bnum的停止条件count次
维护停止点
clear清除所有的已定义的停止点。
clear function清除所有设置在函数上的停止点。
clear linenum清除所有设置在指定行上的停止点。
clear filename:linenum清除所有设置在指定文件:指定行上的停止点。
delete [bp] [range...]删除指定的断点,bp为断点号,简写命令为d。
disable [bnum] [range...] disable所指定的停止点,bp为停止点号,简写dis.
enable [bp] [range...]enable所指定的停止点,breakpoints为停止点号。
enable [bp] once range…enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。
enable [bp] delete range…enable所指定的停止点一次,程序停止后停止点自动删除。
commands [bnum] 批量命令
调试代码
run 运行程序,可简写为r
next 单步跟踪,函数调用当作一条简单语句执行,可简写为n
step 单步跟踪,函数调进入被调用函数体内,可简写为s
finish 退出函数
until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u。
continue 继续运行程序,可简写为c
stepi或si, nexti或ni 单步跟踪一条机器指令
info program 来查看程序的是否在运行,进程号,被暂停的原因。
查看运行时数据
print 打印变量、字符串、表达式等的值,可简写为p
p count 打印count的值
p cou1+cou2+cou3 打印表达式值
p f2.c::x
p *array@len 显示数组
自动显示
display expr 自动显示的变量
display/fmt expr fmt表示显示的格式
display/fmt addr
info display 查看display设置的自动显示的信息。
undisplay dnums…
delete display dnums…
disable display dnums…
enable display dnums…
disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。
历史记录
当你用GDB的print查看程序运行时的数据时,你每一个print都会被GDB记录下来。 GDB会为你每一个print命令编上号。于是,你可以使用这个编号访问以前的表达式
改变程序的执行
print x=4 把变量x的值修改为4
set var width=47
whatis width 查看类型
jump file:line 表示下一条运行语句从哪里开始
jump *address 代码行的内存地址
注意 jump命令不会改变当前的程序栈中的内容,所以,当你从一个函数跳到另一个函数时,当函数运行完返回时进行弹栈操作时必然会发生错误,可能结果还是非常奇怪的,甚至于产生程序Core Dump。所以最好是同一个函数中进行跳转。 熟悉汇编的人都知道,程序运行时,eip寄存器用于保存当前代码所在的内存地址。所以,jump命令也就是改变了这个寄存器中的值。于是,你可以使用“set $pc”来更改跳转执行的地址。如:
set $pc = 0×485
signal signal 产生一个信号量给被调试的程序,UNIX的系统信号量通常从1到15。所以取值也在这个范围。
return
return expression
call expr 调用函数
显示源代码
list linenum
list function 显示函数名为function的函数的源程序
list 显示当前行后面的源程序
list - 显示当前行前面的源程序
set listsize count 设置一次显示源代码的行数
show listsize 查看当前listsize的设置
栈信息
breacktrace,简称bt
backtrace -n 表示只打印栈顶上n层的栈信息。
frame n n是栈中的层编号, frame 0栈顶,frame 1栈的第二层。
frame addr
up n 表示向栈的上面移动n层,可以不打n,表示向上移动一层。
down n 表示向栈的下面移动n层,可以不打n,表示向下移动一层
select-frame 对应于 frame 命令。
up-silently n 对应于 up 命令。
down-silently n 对应于 down 命令
frame 或 f 查看当前栈层的信息
info frame
info f
信号
handle signal[keywords...] signal可以以SIG开头或不以SIG开头,可以用定义一个要处理信号的范围(如:SIGIO-SIGKILL,表示处理从 SIGIO信号到SIGKILL的信号,其中包括SIGIO,SIGIOT,SIGKILL三个信号),也可以使用关键字all来标明要处理所有的信号。一旦被调试的程序接收到信号,运行程序马上会被GDB停住,以供调试。 keywords列表如下:
nostop 当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告诉你收到这种信号。
stop 当被调试的程序收到信号时,GDB会停住你的程序。This implies the print keyword as well.
print 当被调试的程序收到信号时,GDB会显示出一条信息。
noprint当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。This implies the nostop keyword as well.
pass
noignore当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序处理 or else it may terminate if the signal is fatal and not handled.
nopass
ignore当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。
info signals
info handle 查看有哪些信号在被GDB检测中。
设置捕捉点(CatchPoint)
catch 设置捕捉点来补捉程序运行时的一些事件。如载入共享库(动态链接库)或是C++的异常
当event发生时,停住程序。event可以是下面的内容:
throw 一个C++抛出的异常 (throw为关键字)。
catch 一个C++捕捉到的异常 (catch为关键字)。
exec 调用系统调用exec时(exec为关键字,目前此功能只在HP-UX下有用)。
fork 调用系统调用fork时(fork为关键字,目前此功能只在HP-UX下有用)。
vfork 调用系统调用vfork时(vfork为关键字,目前此功能只在HP-UX下有)。
load 或 load 载入共享库(动态链接库)时 (load为关键字,目前此功能只在HP-UX下有用)。
unload 或 unload 卸载共享库(动态链接库)时 (unload为关键字,目前此功能只在HP-UX下有用)。
指定源文件的路径
Directory dirname …
dir dir1:dir2:dir3 如果你要指定多个路径,UNIX下你可以使用“:”,Windows下你可以使用“;”
directory 清除所有的自定义的源文件搜索路径信息。
show directories 显示定义了的源文件搜索路径。
机器语言工具
$pc: 程序计数器
$fp: 帧指针(当前堆栈帧)
$sp: 栈指针
$ps: 处理器状态
原文件的搜索
search text:该命令可显示在当前文件中包含text串的下一行。
Reverse-search text:该命令可以显示包含text 的前一行。
Last updated
Was this helpful?