Linux调试器--gdb的使用
1.背景知识
- 我们在运行我们的代码的时候有两种模式:Debug模式和Release模式。
- 一份代码要被调试,这份代码的发布模式必须是Debug
- 在Linux中我们使用gdb进行调试
安装gdb(这里我用的是CentOS 7.8):
yum install -y gdb
- 在Linux系统中使用gcc编译代码,生成的可执行程序默认是Release模式的。
验证:这里,我们make/makefile编译我写好的test.c文件,生成可执行文件test。
- 在Linux中使用gcc的在Debug模式编译需要用到 - g 选型:
gcc -o 生成可执行文件名 源文件名 -g
这里的 - g选项就是让,指定gcc编译器在Debug模式下,编译源文件。
- 更加形象的区分Debug模式与Release模式:
方法1:
在Debug发布的时候,一定要给可执行程序内部添加Debug信息,否则无法调试
因此导致:Debug形成的可执行文件的大小 > Release形成的可执行文件
方法二:
使用指令:
readelf -S 可执行程序文件名 | grep -i debug
作用:在Linux中形成的可执行程序的格式是ELF格式,而 readelf -S 就是阅读可执行程序,后面的就是通过管道,将文件中的Debug信息筛选出来。如果有Debug信息说明可执行程序文件实在Debug模式下编译的,否则就是Release模式。
2.使用gdb
2.1进入gdb
gbd调试的是可执行文件(debug模式下生成的)!!!
gdb 可执行程序
2.2退出gdb
quit
2.3查看代码
list
list也可以简写成 l
从代码的第一行查看:
list 0 或者 list 1(每次最多打印十行)
在gdb中会自动记录上一次的结果,如下图,在执行一次 list 0 后继续回车会接着打印剩下的代码,直到全显示为之
2.4执行程序
指令:
run
可以简写成: r
2.5打断点
指令:
break 代码行号
break可以简写成 b
作用:在代码的第几行处打断点
我们知道可执行程序文件可以是有多个源文件编译而来的,
2.5.1在指定源文件里打断点:
指令:
b 源文件名:行号
2.5.2在指定源文件里的函数处打断点
指令:
b 源文件名:函数名
2.6查看断点
指令:
info break
2.7 删除断点
指令:
delete break 断点编号
delete break 可以简写为 b
先用指令查看所有断点的编号
info b
然后根据你想删除的断在所在行号,确定断点的编号,然后使用指令就可以删除断点。
d 断点编号
注:在一个gdb的调试周期中断点的编号是一直递增加1的,不会随着断点的删除而减小
同时,在gdb中中的断点,当退出再进时,之前打的段点会全部消失。断点编号也会更新成0.
2.8 启用与禁用断点
注:不管是启用还是禁用断点,断点都一直存在,只不过在禁用断点时的效果和没有断点一样
禁用断点指令:
disable 断点编号
启用断点指令:
enable 断点编号
2.9遇到断点后逐语句走
这里的调试与vs的调试是一样的,逐语句走,遇到函数时,会进入到函数里走。
指令:
step
step可以简写成 s
2.10遇到断点后逐过程走
这里的调试与vs的调试是一样的,逐过程走,遇到函数时,并不会进入函数里,而是直接完成函数到下一行代码。
next
next可以简写成 n
2.11在调试时,查看变量的值
指令:
p 变量名
但是我们从途中看到当我们再次进行操作时,就不会再显示变量的值了,那么如何让才能让变量的值一直显示呢?
指令:
display 变量名
当我们不想查看取消常显示时:
指令:
undisplay 常显示编号
2.12跳转到指定位置
我们再调试时代码时,可能再再到一个循环里,但是当我们确定循环无错时,想要跳出循环到知道行数时:
指令:
until 行号
2.13运行当前函数完成
适用情况:调试到一个函数里,确定这个函数无错,要直接跳出这个函数
指令:
finish
2.14直接从一个断点跑到下一个断点
指令:
continue
continue可以简写成 c
2.15调用堆栈
指令:
bt
2.16 在调试中改变变量的值
指令:
set var 变量名=你想改变成那个数值