GDB的使用简述
- GDB简介
- GDB使用
要调试的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,就可以用gdb来调试他。
gcc -g hello.c -o hello
gdb hello
gdb 调试带参数的程序:gdb --args ./a.out arg1 arg2
- 单步执行
continue(简写 c): 继续执行程序,直到下一个断点或者结束;
step (简写s):单步调试,如果有函数调用,则进入函数; step <count>表示执行后面的count条指令,然后再停住。
si:执行下一条指令(指令级)
next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到· 函数中去运行,而 next 则直接调用函数,不会进入到函数体内。step(简写 s) :单步执行程序,但是遇到函数会进入函数;
until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体;
until+行号: 运行至某行,不仅仅用来跳出循环;
finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息;
call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55);
run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。如果没有断点,程序将一直执行直到遇到错误或者结束。
- 设置断点
break n (简写b n):在第n行处设置断点。(可以带上代码路径和代码名称: b file1.c:578)
b fn1 if a>b:条件断点设置
break func(break缩写为b):在函数func()的入口处设置断点
delete 断点号n:删除第n个断点
disable 断点号n:暂停第n个断点
enable 断点号n:开启第n个断点
clear 行号n:清除第n行的断点
info b (info breakpoints) :显示当前程序的断点设置情况
delete breakpoints:清除所有断点
- 打印表达式
print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
print a:将打印变量 a 的值
print ++a:将把 a 中的值加1,并显示出来
print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
whatis :查询变量或函数
info function: 查询函数
扩展info locals: 显示当前堆栈页的所有变量
- 查看内存单元值
gdb中使用examine命令(缩写x)来打印内存的值,格式为"x/nfu addr"。含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:
a) n:输出单元的个数。
b) f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。
x(hex) 按十六进制格式显示变量。
d(decimal) 按十进制格式显示变量。
u(unsigned decimal) 按十进制格式显示无符号整型。
o(octal) 按八进制格式显示变量。
t(binary) 按二进制格式显示变量。
a(address) 按十六进制格式显示变量。
c(char) 按字符格式显示变量。
f(float) 按浮点数格式显示变量
c) u:标明一个单元的长度。b是一个byte,h是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)
举例:
以16进制格式打印从add开始的16个byte的值:
(gdb) x/16xb $r11
0xbefffc64: 0x6c 0xfc 0xff 0xbe 0x00 0x00 0x00 0x00
0xbefffc6c: 0xc4 0xcc 0xfc 0xb6 0x00 0x90 0xfd 0xb6
- list(简写l):查看源程序
list <linenum> 显示程序第linenum行周围的源程序
list <function> 显示函数名为function的函数的源程序
list 显示当前行后面的源程序。
list - 显示当前行前面的源程序。
- info命令
info registers (查看除了浮点寄存器以外的寄存器)
info all-registers (查看所有寄存器,包括浮点寄存器)
info registers <regname ...> (查看所指定的寄存器)
info break 查看断点信息
Num(断点编号)
Disp:断点执行一次之后是否有效 kep:有效 dis:无效
Enb: 当前断点是否有效 y:有效 n:无效
Address:内存地址
What:断点位置
info watchpoints 列出当前所设置的所有观察点
info line命令来查看源代码在内存中的地址。
info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式,打印出所指定的源码在运行时的内存地址
- 栈帧相关
(gdb) frame
#0 func1 (a=11, b=22) at hello.c:17
17 in hello.c
info frame 打印当前栈帧的详细信息。
(gdb) info frame
Stack level 0, frame at 0xbefffc68:
pc = 0x8434 in func1 (hello.c:17); saved pc 0x8454
called by frame at 0xbefffc70
source language c.
Arglist at 0xbefffc64, args: a=11, b=22
Locals at 0xbefffc64, Previous frame's sp is 0xbefffc68
Saved registers:
r11 at 0xbefffc64
info frame[level]打印指定栈帧的详细信息
Stack frame at 0xbefffc70:
pc = 0x8454 in main (hello.c:22); saved pc 0xb6fcccc4
caller of frame at 0xbefffc68
source language c.
Arglist at 0xbefffc6c, args:
Locals at 0xbefffc6c, Previous frame's sp is 0xbefffc70
Saved registers:
r11 at 0xbefffc68, lr at 0xbefffc6c
info args 打印当前栈帧的参数信息
(gdb) info args
a = 11
b = 22
info locals 打印当前栈帧局部变量的信息。
(gdb) info locals
c = 0
- disassemble [函数名或者地址]:反汇编当前函数或者指定的函数
- cgdb强大工具
cgdb主要功能是在调试时进行代码的同步显示,这无疑增加了调试的方便性,提高了调试效率。界面类似vi,符合unix/linux下开发人员习惯;如果熟悉gdb和vi,几乎可以立即使用cgdb。
- 分割窗口
layout src:显示源代码窗口
layout asm:显示反汇编窗口
layout regs:显示源代码/反汇编和CPU寄存器窗口
layout split:显示源代码和反汇编窗口
Ctrl + L:刷新窗口
Ctrl + X A 退出源代码窗口
- 查看运行信息
where/bt :当前运行的堆栈列表;
bt backtrace 显示当前调用堆栈,最近被调用的函数在 0 号帧中 (栈顶)。
backtrace n 表示只打印栈顶上 n 层的栈信息 (n 为正整数);相反地,backtrace -n 表示只打印栈底下 n 层的栈信息。
- 退出gdb
quit:简记为 q ,退出gdb
sum栈帧的返回
leave= mov %ebp,%esp
pop %ebp
ret= pop %eip
累。就这样吧。
参考资料:http://www.sourceware.org/gdb/
https://blog.csdn.net/niyaozuozuihao/article/details/91802994
https://www.cnblogs.com/black-mamba/p/7061248.html
https://www.cnblogs.com/mingcaoyouxin/p/4225619.html
https://www.cs.umd.edu/~srhuang/teaching/cmsc212/gdb-tutorial-handout.pdf
2022/3/23
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?