【Linux】调试器---gdb的使用


一.背景知识

  1. 程序的发布方式有两种,debug(调试)模式和release(发行)模式;
  2. Linux gcc/g++出来的二进制程序,默认是release模式;
  3. gdb是Linux中的调试器。用于debug版本代码的调试, 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上-g选项

二.安装gdb

sudo yum install gdb //想直接安装就加上-y选项

三.gdb的用法

为了详细解析gdb的各种用法,我们先创建两个文件:test.c和Makefile文件,用于测试gdb。
在这里插入图片描述
以下分别是两个文件中的测试代码:

//test.c:我们用一个从1加到100的程序来测试gdb
#include<stdio.h>
 
 int addToTop(int top)
 {
    
    
     printf("enter addToTop\n");
 
     int sum=0;
     for(int i=1;i<=top;i++)
     {
    
    
         sum+=i;
     }
     printf("quit addToTop\n");
     return sum;                                                                                                                                                                  
 }
 int main()
 {
    
    
     int top=100;
 
     int ret=addToTop(top);
     printf("ret:%d\n",ret);
     return 0;
 }


//Makefile(自动化构建项目的工具)
mytest:test.c //依赖test.c文件生成mytest可执行程序
     gcc test.c -g -o mytest -std=c99 //注意这里加上了-g选项,也用上了c99标准                                                                                                                                        
.PHONY:
make clean:
     rm -f mytest

运行结果
在这里插入图片描述

使用须知

程序的发布方式有两种:

  • debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
  • release版本:不会添加任何调试信息,是不可调试的。

在Linux当中gcc/g++默认生成的可执行程序是release版本的,是不可被调试的。如果想生成debug版本,就需要在使用gcc/g++生成可执行程序时加上-g选项。
在这里插入图片描述
我们可以使用readelf指令查看ELF格式的文件信息:
在这里插入图片描述对同一份源代码分别生成其release版本和debug版本的可执行程序,debug版本发布的可执行程序的大小比release版本发布的可执行程序的大小要大一点,从上图我们可以看出debug版本中有debug信息,其原因就是以debug版本发布的可执行程序当中包含了更多的调试信息。

gdb的常用指令

1.进入调试

gdb [可执行程序] //在上述我们写的测试代码中,可执行程序命名为mytest
//所以接下来我们就以mytest为例

2.退出调试操作

ctrl+d 或 quit

3.显示源代码

list/l 行号:显示源代码,如果按换行键会接着上次显示的位置往下列,每次只显示10行
list/l 函数名:可以直接定位到函数名的位置

操作示例
在这里插入图片描述
在这里插入图片描述

4.设置断点breakPoint

beak(b) 行号:在某行设置一个断点
b 函数名:在某个函数开头设置断点

操作示例
意思是在源代码的第19行设置断点
在这里插入图片描述
意思是在源代码的addToTop函数开头设置断点,会自动识别到第5行(函数所在处)
在这里插入图片描述

5.查看断点信息/禁用断点/开启断点/删除断点

info b(break)

info b指令会显示出所有的断点,我们刚刚设置了两个断点,所以显示出了两个断点的信息,Num是断点的编号,Enb表示断点的状态,y表示断点正常使用,n表示断点已被禁用。
在这里插入图片描述
想要操作哪个断点不是看这个断点在代码中的行号,而是在断点列表的编号。
禁用断点

disable [断点编号Num]

开启断点

enable [断点编号Num]	

删除断点

d(delete) [断点编号] //不加断点编号,则删除所有已设置的断点

6.运行程序,开始调试run

运行程序后会在断点处停下,就跟我们在Windows下用vs编译器调试一样一样的。不设置断点的话,程序就直接跑完了,并输出结果。

r或run

在这里插入图片描述

7.查看变量

打印变量值

p 变量名

在这里插入图片描述

跟踪查看一个变量(长显示)

display 变量名

在这里插入图片描述

取消对变量的跟踪(取消长显示)

undisplay 变量名

8.其它重要命令

  • set var i=100:将某个变量设置成特定的值
  • continue(或c):从一个断点处,直接运行到下一个断点处
  • until 行号:在函数内,进行指定位置跳转,执行完区间代码
  • bt(或breaktrace):查看调用堆栈
  • info (i)locals:查看当前栈帧局部变量的值
  • n或next:逐过程执行代码
  • s或stap:逐语句执行代码,可以进入函数体内
  • finish:进入一个函数,只执行完该函数,就停下来,比如上述所例举的从1加到100的函数,如果我们这个时候还在执行for循环,我们直接输入finish,就可以直接指向完addToTop函数。
  • print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • info:查看gdb的使用手册

猜你喜欢

转载自blog.csdn.net/weixin_63449996/article/details/130129003