目录
文章目录
一、GDB 简介
GDB是Linux下是调试程序的必备工具,相对于打印输出或打印日志,其能让我们检查程序的每一步执行,发现问题所在。要使用gdb调试可执行程序,gcc/g++编译时要加上参数-g,gcc/g++ -g 编译时会加入调试信息,gdb 指令不能加;号。
gcc/g++ -g main.c生成可调试的执行文件gdb -p pid调试某个进程 pid->进程号gdb main.out调试可执行文件gdb -c core.xxx main.out调试core文件
二、GDB 指令速览
| 指令 | 全称 | 作用 |
|---|---|---|
$ gdb -tui | 启动gdb,分屏显示(上半部分源代码,下半部分gdb调试控制台),上下方向键滚动源代码,[Ctrl]n、[Ctrl]p翻滚指令记录 | |
$ gdb <app> | 启动gdb,并调试程序<app> | |
$ gdb -p <PID> | 启动gdb,并调试进程<PID> | |
$ gdb <app> <PID> | 启动gdb,调试进程号为<PID>的<app>可以使用:l / b / c / n / s / p 等 | |
(gdb) help | 显示gdb help信息 | |
(gdb) file <app> | 载入可执行程序<app> | |
(gdb) l | list | 列出源码 |
(gdb) [Enter] | 直接回车,重复执行上一条指令 | |
(gdb) b <line> | break | 设置断点,在lines行处 |
(gdb) b <func> | break | 设置断点,在函数func第一行处 |
(gdb) break x.cpp:21 | break | 设置断点,在源文件x.cpp的21行处 |
(gdb) info break | 查看断点信息 | |
(gdb) delete | 删除所有断点 | |
(gdb) delete <断点号N> | 删除N号断点 | |
(gdb) r | run | 运行程序,可以加参数 |
(gdb) n | next | step over |
(gdb) s | step in | |
(gdb) c | continue | 继续执行到下一个可用断点或结束 |
(gdb) p <变量> | print | 打印变量的值 |
(gdb) u | until | 退出循环(光标可能需要停在循环的开头或结尾处) |
(gdb) finish | 退出函数 | |
(gdb) x/s <0x...地址> | examine | 以字符串的形式显示该地址的值 |
(gdb) set var i=3 | 设置变量i的值 | |
(gdb) q | quit | 退出gdb |
(gdb) attach <PID> | gdb接<PID>进程,进程停在某个点 | |
(gdb) detach | gdb释放该进程,进程继续运行 |
三、GDB 常用指令介绍
1、载入程序命令
file <app>载入可执行程序<app>
2、设置断点
break设置断点,可以简写为b (后面断点全部简写成b)b 10在源程序第10行,设置断点b func在func函数入口处,,设置断点b filename:linenum在源文件filename的linenum行,设置断点b filename:function在源文件filename的function函数的入口处,设置断点b 类名::function或function(type,type)在类class的function函数的入口处,设置断点b namespace::类名::function在名称空间为namespace的类class的function函数的入口处,设置断点
C++程序中可以使用class::function或function(type,type)格式来指定函数名。如果有名称空间,可以使用namespace::class::function或者function(type,type)格式来指定函数名。
3、设置观察点
watch在指定变量/内存地址(表达式)expr设置一个watchpoint。一但expr值有变化时,将停住程序。rwatch当expr被读时,停住程序。awatch当expr被读或被写时,停住程序。info watchpoints列出当前所设置了的所有观察点。
在使用watch时步骤如下:
- 使用break在要观察的变量所在处设置断点;
- 使用run执行,直到断点;
- 使用watch设置观察点;
- 使用continue观察设置的观察点是否有变化。
4、断点管理
clear清除所有的已定义的断点。clear function清除所有设置在函数上的断点。clear linenum清除所有设置在指定行上的断点。clear filename:linenum清除所有设置在指定文件:指定行上的断点。delete [breakpoints] [range…]删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range表示断点号的范围(如:3-7)。其简写命令为d。disable断点disable了的断点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。disable [breakpoints] [range…]disable所指定的断点,breakpoints为断点号。如果什么都不指定,表示disable所有的断点。简写命令是dis.enable [breakpoints] [range…]enable所指定的断点,breakpoints为断点号。enable [breakpoints] once [range…]enable所指定的断点一次,当程序停止后,该断点马上被GDB自动disable。enable [breakpoints] delete [range…]enable所指定的断点一次,当程序停止后,该断点马上被GDB自动删除。
5、查看源代码
list/l显示当前行后面的源程序list linenum显示程序第linenum行的周围的源程序list function显示函数名为function的函数的源程序list filename:linenum显示指定文件指定行的前后代码list filename:function显示指定文件中的指定函数的前后代码list first, last显示从first行到last行之间的源代码set listsize count设置一次显示源代码的行数show listsize查看当前listsize的设置,默认为10
6、运行控制
-
run运行程序,可简写为r -
run [arg1] [arg2]运行程序,并传递参数arg1、arg2给程序 -
continue继续执行程序,可简写为c -
next单步跟踪,函数调用当作一条简单语句执行,可简写为n -
step单步跟踪,函数调用会进入被调用函数体内,可简写为s -
finish退出函数,返回调用函数。打印函数返回时的堆栈地址和返回值及参数值等信息 -
until在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u -
nexti或ni单步跟踪一条机器指令 -
stepi或si单步跟踪一条机器指令,一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令
-
backtrace/bt显示程序中当前位置及到达当前位置的栈帧 -
info b查看所有的断点信息 -
whatis查看变量类型 -
info program来查看程序的是否在运行,进程号被暂停的原因。 -
set var i=3设置变量的值
7、查看变量
print/[fmt] <变量/字符串/表达式>打印变量、字符串、表达式等的值,可简写为pdisplay/[fmt] <地址/表达式>在程序停止时自动打印地址、表达式的值examine/<n/f/u> <addr>查看内存地址中的值,可简写为xx/s <0x...地址>以字符串的形式显示该地址的值
打印输出格式
GDB的数据显示格式:p/x 变量/字符串/表达式
x按十六进制格式显示变量d按十进制格式显示变量u按十六进制格式显示无符号整型o按八进制格式显示变量t按二进制格式显示变量a按十六进制格式显示变量c按字符格式显示变量f按浮点数格式显示变量
examine命令格式
x/<n/f/u> <addr>
n,表示显示内存的长度,f表示显示的格式 GDB会根据变量的类型输出变量的值,也可以指定s按字符格式显示i按指令格式显示x按十六进制格式显示变量。d按十进制格式显示变量。u按十六进制格式显示无符号整型。o按八进制格式显示变量。t按二进制格式显示变量。a按十六进制格式显示变量。c按字符格式显示变量。f按浮点数格式显示变量。
u表示从当前地址往后请求的地址单元的长度, GDB默认是w。b表示单字节,h表示双字节,w表示四字节,g表示八字节
<addr>表示一个内存地址。
例如:
x/3uh 0x54320
表示:
- 从内存地址
0x54320读取内容, - 3表示三个单位
- u表示按十六进制显示
- h表示以双字节为一个单位
8、窗口分割命令
layout用于分割窗口,可以一边查看代码,一边测试。layout src显示源代码窗口layout asm显示汇编窗口layout regs显示源代码/汇编和寄存器窗口layout split显示源代码和汇编窗口layout next显示下一个layoutlayout prev显示上一个layoutCtrl + L刷新窗口Ctrl + x,再按1单窗口模式,显示一个窗口Ctrl + x,再按2双窗口模式,显示两个窗口Ctrl + x,再按a回到传统模式,即退出layout,回到执行layout之前的调试窗口focus cmd/src/asm/regs/next/prev切换当前窗口refresh刷新所有窗口tui reg next显示下一组寄存器tui reg system显示系统寄存器update更新源代码窗口和当前执行点winheight name +/- line调整name窗口的高度tabset nchar设置tab为nchar个字符tabstop nchar设置tab为nchar个字符tabstop查看tab的设置
9、查看寄存器
info registers查看寄存器信息info all-registers查看所有寄存器信息info registers <regname>查看指定寄存器信息info registers <regname1> <regname2>查看多个寄存器信息info frame查看当前栈帧信息info args查看当前栈帧的参数info locals查看当前栈帧的局部变量info variables查看当前栈帧的所有变量info functions查看当前栈帧的所有函数info functions <function>查看当前栈帧的指定函数info functions <function1> <function2>查看当前栈帧的多个函数

5776

被折叠的 条评论
为什么被折叠?



