gdb的概述
GDB 全称"GNU symbolic debugger",从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。一般来说,GDB主要帮助我们完成以下四个方面的功能:
- 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
- 在某个指定的地方或条件下暂停程序。
- 当程序被停住时,可以检查此时你的程序中所发生的事。
- 在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug。
背景
- 程序的发布方式有两种,debug模式和release模式
- Linux gcc/g++出来的二进制程序,默认是release模式
- 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项
debug模式和release模式的区别
如果你想要让程序可以调试必须让其程序以debug模式进行发布。
像我们vs2022里面也是有这两种模式的,里面想要调试程序只需将其切换成debug模式方可调试
那么问题来了,一般我们的gdb进入的时候都有一个默认的模式,如何知道他是debug模式还是release模式呢?下面我们简单写一段代码来验证一下。
创建一个自动化构建工具Makefile文件
然后执行下make会自动编译形成一个可执行文件mycode,./mycode执行该程序是正常运行的。
在linux下,我们编译代码的时候,默认是release模式。如何证明呢?
我们上面说了,release模式下的程序是不可被调试的,我们只需要证明可执行程序mycode是不可被调试的即可。在linux下我们要证明一个程序是否能够被调试需要用到一个工具gdb。
以上是我的云服务器centos7下的gdb的版本,下面我们在该环境下进行使用测试
如果我们想让可执行程序mycode在gdb下被调试,只需要在gcc编译时加一个-g选项
下面我们重新编译下
如果你想要你的代码以debug 模式发布,必须给gcc添加-g选项
那么我们debug模式下形成的可执行程序和release模式下形成的可执行程序有什么区别呢?
其实debug 模式下形成的可执行程序 相对于release模式下形成的可执行程序加了一些调试信息
我们将mycode.c形成两个可执行程序一个是debug模式的,一个是release模式的
我们在Linux中形成的可执行程序格式是ELF格式的
所以我们可以通过readelf命令读取可执行文件的格式信息
开始使用
gdb binFile 退出: ctrl + d 或 quit 调试命令:
- list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
使用演示过程:
- list/l 函数名:列出某个函数的源代码。
- r或run:运行程序。
- n 或 next:单条执行。
- s或step:进入函数调用
- break(b) 行号:在某一行设置断点
- break 函数名:在某个函数开头设置断点
- info break :查看断点信息。
-
finish:执行到当前函数返回,然后停下来等待命令
-
print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
- p 变量:打印变量值。
- set var:修改变量的值
- continue(或c):从当前位置开始连续而非单步执行程序
- run(或r):从开始连续而非单步执行程序
- delete breakpoints:删除所有断点
- delete breakpoints n:删除序号为n的断点
- disable breakpoints:禁用断点
- enable breakpoints:启用断点
- info(或i) breakpoints:参看当前设置了哪些断点
- display 变量名:跟踪查看一个变量,每次停下来都显示它的值
- undisplay:取消对先前设置的那些变量的跟踪
- until X行号:跳至X行
- breaktrace(或bt):查看各级函数调用及参数
- info(i) locals:查看当前栈帧局部变量的值
- quit:退出gdb
当你退出gdb的时候打的断点信息全部被清除
退出前:
退出后重新进入
如何理解gdb?
可以跟windows IDE对应,比如vs2022的调试