目录
前言:
debug VS realse
GDB的基本操作
行号显示
设置断点
编辑
查看断点信息
删除断点
禁用断点
开启断点
运行
逐过程
逐语句
显示/追踪变量
查看调用堆栈
指定行号跳转
强制执行函数
断点间跳转
修改变量的值
前言:
GDB(GNU symbolic debugger)是GNU开源组织发布的一个强大的Unix/Linux下的程序调试工具,可以调试多种语言,
vs环境中是通过图形化页面进行操作,而在Linux环境下则是进行纯文本的操作
GDB具有如下四个方面的的功能:
- 启动你的程序,按照自定义的方式随心所欲的运行程序;
- 在某个指定的位置或条件下暂停程序;
- 当程序停住时,可以查看变量,寄存器,内存及堆栈;
- 在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug;
debug VS realse
程序的发布方式有两种,debug模式和release模式;其中debug为调试版本,而release为发布版本,debug与release版本对比如下:
编译方式:Debug版本通常使用无优化的编译方式,以便在调试过程中能够更好地跟踪代码执行过程,而Release版本则使用优化的编译方式,以提高程序的执行效率;
调试信息:Debug版本会包含完整的调试信息,包括变量名、函数名等,以便在调试过程中能够更好地理解代码的执行情况,而Release版本会删除调试信息,以减小程序的体积;
错误检测:Debug版本通常会开启各种错误检测机制,例如内存泄漏检测、数组越界检测等,以便在开发过程中能够及时发现和修复问题;而Release版本则会关闭这些错误检测机制,以提高程序的执行速度;
注: Linux gcc/g++编译与链接生成的可执行文件,默认为release模式;
调试时使用的源代码为test.c
makefile文件内容如下:
进入gdb调试器的指令:gdb 可执行文件名
退出gdb调试器的指令:quit
验证了Linux gcc/g++编译与链接生成的可执行文件,默认为release模式;
由于release模式下可执行文件不包含调试信息,所以无法调试,若想生成的可执行文件为debug模式,需要编译链接时加上 -g 选项 ;修改makefile文件如下:
此处验证了Debug版本的可执行文件体积大,而Release版本的可执行文件体积小;
由于生成的可执行文件是一个二进制文件,使用指令 readelf -S 可执行文件名 查看可执行文件的信息;
使用指令 readelf -S 可执行文件名 | grep -i debug 查看可执行文件中所包含的调试信息;
此处验证了debug版本的可执行文件包含调试信息;
GDB的基本操作
行号显示
l(list) 行号/函数名 --- 显示对应的的源代码,默认显示10行
由于gdb自动记忆上次键入的指令,直接按Enter键便可浏览代码剩余部分;
设置断点
断点的作用: 通过设置断点,程序会在断点处停止执行;
b(breakpoint) + 行号 --- 在该行设置断点
b(breakpoint) 源文件名:行数(n) ---- 在该源文件的第n行设置断点
b 函数名 ---给当前调试的源文件中的某函数的第一行设置断点
b 源文件:函数名 ---给指定的源文件中的某函数的第一行设置断点
查看断点信息
info b ---- 查看断点信息
删除断点
d 断点编号n----删除n号断点
d breakpoints ---- 删除所有断点
禁用断点
disable b ---- 使所有断点无效
disable b 编号n ----使n号断点无效
开启断点
enable b 编号n ---- 使n号断点有效
enable b ---- 使所有断点有效
运行
- 没有断点键入 r 直接运行到程序结束
- 存在断点运行到第一个断点处停止运行
逐过程
n(next) ---- 相当于vs环境中的F10,用于排查函数是否出错
逐语句
s(step) ---- 相当于vs环境中的F11,一次执行一条语句,可进入函数内部
显示/追踪变量
p(print) 变量名/&变量名 ---- 查看变量的值与地址
每次执行一条语句结束时,若想查看变量的值,都需要手动输入指令,太过于繁琐;
display 变量名/&变量名 ---- 跟踪查看变量的值与地址,每次执行指令结束后显示其值
undisplay 变量名编号n ---- 取消对n号变量的跟踪
查看调用堆栈
bt --- 查看调用堆栈
指定行号跳转
until 源代码行号 ----首先执行完区间代码,然后跳转到指定位置
强制执行函数
程序员在初步排查时推断可能是某个函数内部的代码逻辑出现问题,但是不采用逐语句的方式进入到函数内部进行调试,首先进入到函数内部,然后使用finish;
finish ---- 在某个函数内部使用,将该函数运行结束后停止
断点间跳转
c(continue) ---- 从一个断点处,运行至下一个断点处
修改变量的值
修改test.c文件如下图所示:
set var 变量名=变量值 ---- 使用gdb调试时修改变量值,无需修改源代码,实现多分支测试