gdb断点调试
-
start #开始调试,停在第一行代码处,(gdb)start
-
l #list的缩写查看源代(gbb)l [number/function]
-
b#b: Breakpoint的简写,设置断点。(gdb)b 10
-
b#b: Breakpoint的简写,设置断点。(gdb)b main
-
b filename:[line/function] #b:在文件filename的某行或某个函数处设置断点
设置条件断点
(gdb)break 46 if testsize == 100
在当前文件某一行(假设为6)设定断点
(gdb)break xxx.c:6
断点内存地址
b *free if $rdi == 0x234567
-
i breakpoints #i:info的简写。(gdb) i breakpoints
-
d [dpNO] #d:Delete breakpoint的简写,删除指定编号的某个断点或删除所有断点。断点编号从1开始递增。(gdb) d 1
-
s #s:step执行一行源程序代码,如果此行代码中有函数调用,则进入该函数(gdb) s
-
n #n:next执行一行源程序代码,此行代码中的函数调用也一并执行。(gdb) n
-
r #r:Run的简写, 运行被调试的程序。如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。(gdb)r
-
c #c:Continue的简写,继续执行被调试程序,直到下一个断点或程序结束(gdb) c
-
finish #函数结束
-
p #p:Print的简写,显示指定变量(临时变量或全局变量,例如int a)的值 (gdb) p a
print 操作符
@
是一个和数组有关的操作符,在后面会有更详细的说明。(gdb) p *array@len
::
指定一个在文件或是一个函数中的变量。
{}
表示一个指向内存地址的类型为tye的一个对象。
2.查看内容
全局变量(所有文件可见的)
静态全局变量(当前文件可见的)
局部变量(当前Scope可见的)
3.输出格式
x按十六进制格式显示变量。
d按十进制格式显示变量。
u按十六进制格式显示无符号整型。
o按八进制格式显示变量。
t按二进制格式显示变量。
a按十六进制格式显示变量。
c按字符格式显示变量。
f按浮点数格式显示变量。
4.查看内存
使用examine(简写x)来查看内存地址中的值。语法: x/
n,f,u是可选参数。
(1)n是一个正整数,比那时显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
(2)f表示显示的格式,参见上面。如果地址所指的时字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i。
(3)u表示从的那个前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定内存的内存地址开始,读写指定字节,并把其当作一个值取出来。
eg:
x/3uh 0x54320 :从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。
5.查看寄存器
(1)要查看寄存器的值,很简单,可以使用如下命令:
info registers
(2)查看寄存器的情况(除了浮点寄存器),可以使用如下命令:
info all-registers
(3)查看所有寄存器的情况(包括浮点寄存器),可以使用如下命令:
info register
(4)查看所指定寄存器的情况:
寄存器中放置了程序运行时的数据,比如程序当前运行的指令地址(ip),程序的当前堆栈地址(sp)等等。你同样可以使用print命令来访问寄存器的情况,只需要在寄存器名字前加一个$符号就可以了。如:p $eip。
6.设置
(1)set ptint address
set print address on
打开地址输出,当程序显示函数信息时,GDB会显除函数的参数地址。
(2)set ptint array
set print arrayon
打开数组显示, 打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。
(3) set print elements
这个选项主要时设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不在往下显示了。如果设置为0,则表示不限制。
(4)set ptint null-stop
如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。
(5)set print pretty on
如果打开print pretty这个选项,那么当GDB显示结构体时会比较漂亮。如:
$1={
next= 0x0,
flags = {
sweet = 1,
sour = 1
},
meat = 0x54 "Pork"
}
(6)set print union
设置显示结构体时,是否显式其内的联合体数据。
(7)set print object
在c++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了。
-
display [var] #display,设置想要跟踪的变量(例如 int a)。(gdb) display a
-
undisplay [var] #undisplay,取消对变量的跟踪,被跟踪变量用整型数标识。(gdb) undisplay a
-
set [args] #set可指定运行时参数。(gdb) set a = 10
-
show [args] #show可查看运行时参数。
-
q #Quit的简写,退出GDB调试环境。(gdb) q
-
help [cmd] #GDB帮助命令,提供对GDB各种命令的解释说明。如果指定了“命令名称”参数,则显示该命令的详细说明了;如果没有指定参数。则分类显示所有GDB命令,供用户进一步浏览和查阅。(gdb)help
-
回车(Enter)#重复前面的命令,(gdb)回车
-
list/l 命令 #可以使用Iist/l命令查看程序,方便我们添加断点时查看信息。
- list+lineNumber(中间有空格) - list 打印函数名称为Function的函数上下文的源程序 - list 输出当前行后面的代码 - list -显示当前行前面的代码
-
watch命令 #watch命令一般来观察某个表达式(变量也可视为一种表达式)的值是否发生了变化,如果由变化则程序立即停止运行,具体用法如下:
watch <expr> 为表达式(变量)expr设置一个观察点一旦其数值由变化,程序立即停止运行 rwatch <expr> 当表达式expr被读时,程序立即停止运行 awatch <expr>当表达式expr的值被读或写时程序立即停止运行 info watchpoints 列出当前所设置的所有观察点 检测表达式变化则停住 (gdb) watch i != 10 这里 1 !=10这个表达式一旦变化,则停住。watch <expr>为表达式(变量)expr设置一个观察点。一旦表达式有变化时,马上停住程序(也是一种断点)。
-
return命令 #如果函数中设置了调试断点,在断点后还有语句没有执行完,这个时候我们可以使用return命令强制函数忽略还没有执行的语句并返回。可以直接使用return命令用于取消当前函数的执行并立即返回函数值,也可以指定表达式如return那么该表达式的值会被作为函数的返回值。
-
info命令 #info命令可以用来在调试时查看寄存器,断点,观察点和信号等信息
其用法如下: info registers: info all-registers: info registers: info break: info watchpoints: info signals info handle查看有哪些信号正在被gdb检测 info line: info threads: info frame查看当前函数的程序语言
-
jump #跳转执行程序到第5行,另外跳转不会改变当前的堆栈内容,所以跳到别的函数中就会有奇怪的现象,因此最好跳转在一个函数内部进行,跳转的参数可以是程序代码行的地址,函数名等等类似。 (gdb) jump 5
-
call #强制调用函数。这里可以是一个函数,这样就会返回函数的返回值,如果函数的返回类型是void那么就不会打印函数的返回值,但是实践发现,函数运行过程中的打印语句韩式没有被打印出来。 (gdb) call
-
set #1.手动设置当前的程序语言为c++ (gdb)set language c++ 这里, 如果gdb没有检测出你的程序语言,你可以这样设置。
2.查看可以设置的程序语言 (gdb) set language 这里, 使用没有参数的set language可以查看gdb中可以设置的程序语言。 3.终止-一个正在调试的程序 (gdb) kill
-
thread apply all #查看当前进程所有线程调用栈
-
dump memory #从正在运行的Linux进程中dump出内存内容