文章目录
- 一、背景知识介绍
- 二、gdb常用指令
一、背景知识介绍
程序的发布方式有两种,Debug模式和release模式。Debug是开发者模式,而用户最终使用的是release。Debug模式下的代码,可以被追踪、调试,因为在Debug模式下形成的可执行程序,里面添加了debug信息。这意味着,以Debug模式下得到的可执行程序,一定比release模式下得到的可执行程序要大。gcc编译器,默认是以release的模式编译得到可执行程序,要在Debug模式下,编译得到可执行程序,需要加-g选项,如下:
gcc mycode.c -o mycode -g
readelf mycode_Debug -S//查看一个可执行程序对应的二进制文件
readelf mycode_Debug -S | grep debug//将二进制文件中和debug有关的部分过滤出来
通过上面的指令,可以查看可执行程序所对应的二进制文件,其中mycode_Debug
是在Debug模式下编译得到的一个可执行程序,它里面就包含Debug信息。
总结:要想被gdb调试,必须以Debug方式发布,即在执行gcc/g++指令的时候需要添加-g
选项。
二、gdb常用指令
#include <stdio.h>
int AddTop(int top)
{
int res = 0;
int i = 1;
for(; i <= top; i++)
{
res += i;
}
return res;
}
int main()
{
printf("Debug begin\n");
int top = 100;
int sum = AddTop(top);
printf("sum:%d\n",sum);
printf("Debug end\n");
return 0;
}
我将以上面这段代码为例,为大家演示gdb的使用方法。
gdb binFile
:进入gdb环境,其中binFile是一个可执行程序。
-
ctrl+d
或q+enter
:退出gdb环境。 -
list
或l
:显示binFile
的源代码,接着上次的位置往下列,每次10行。
l num
或list num
:其中num是行号,将源代码的第num行在中间位置显示。
小Tips:如果我们希望看到完整的源代码,可以用l 0
,其次因为gdb会自动记录最近一条指令,当我们执行完l 0
后,gdb会将l
指令记录下来,我们只需要点击enter
,gdb就会自动去执行它所记录的指令,这样我们就可以看到完整的源代码啦。
list Func
或l Func
:其中Func是函数名,列出某个函数的源代码。
run
或r
:运行程序。
break(b) 行号
:在某一行设置断点。
info break(b)
:查看断点信息。
d Num
:删除一个断点,其中Num是断点编号。
小Tips:如果在调试过程中退出,那么再次进入调试环境,上一次的调试信息会丢失,即之前设置的断点都没了。
-
n
或next
:逐过程,单条执行,当有函数调用时,不会进入函数内部。 -
s
或step
:逐语句,进入函数调用。 -
p 变量
:打印变量的值。
小Tips:通过p
来打印变量的值,不会根据我们调试的进行而实时变化。
display 变量名
:跟踪查看一个变量,每次停下来都显示它的值。
-
undisplay num
:取消对先前设置的那些变量的追踪,其中num是先前设置的跟踪变量所对应的编号。 -
until x
:跳至x行,可以让我们快速的运行代码块。
finish
:执行完当前函数返回,然后停下来等待命令。
小Tips:finish
指令可以快速的帮我们查看问题是不是出在当前函数中。
continue
或c
:从当前断点直接运行到下一个断点处。
disable Num
:禁用断点,其中Num
是断点编号。
-
enable Num
:启用断点,其中Num
是断点编号。 -
b 函数名
:在某个函数开头设置断点。 -
b mycode.c:line
:在mycode.c这个源文件的第line行设置断点。(line表示行号) -
b mycode.c:main
:在mycode.c源文件的main函数处打断点。 -
set var
:修改变量的值。 -
bt
:查看各级函数调用及参数。 -
info locals
:查看当前函数栈帧中所有局部变量的值。
🎁结语:
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是春人前进的动力!