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

news/2024/11/18 3:31:08/

目录

  • 1.debug和release
    • 拓展
  • 2.如何使用gdb调试
  • 3.指令集

我们平常调试C/C++代码大多实在Windows平台下的VS中,在LInux中,我们通常使用gdb来调试代码,虽然我们很少在LInux上对代码进行调试,gdb在实际的使用中用的较少,但我们必须要懂它,以面对各种环境。

本文目的:能够进行基本的掌握单进程程序的调试,即使用VS 2019、VS 2022的基本调试功能,都在Linux上使用gdb实现。

本文会在Linux环境下使用到vim编辑器make/Makefilegcc/g++,如果对这三个工具不熟悉,可点击下面的链接,结合本文一起学习。
vim编辑器
make/Makefile
gcc/g++

1.debug和release

在学习Linux下使用gdb调试之前,我们需要掌握以下三个有关debug和release模式的铺垫知识

  1. 程序的发布方式有两种,debug模式和release模式

    debug模式:该模式是程序员编写程序和调试代码的模式,该模式下生成的可执行程序含有调试信息体积要大于release模式生成的可执行程序

    release模式:没有调试信息,对程序做出优化,减小了程序的体积,更适合用户使用。该模式下生成的可执行程序是公司最终要推向市场的,由公司内测试人员测试是否完善,测试通过后推向市场。

    • 注意: debug模式下可以调试,release模式下无法调试。

    下图是VS 2019下,两种模式的选择图,需要那种模式选择那种模式即可
    在这里插入图片描述
    那在Linux下如何进行两个模式的转换呢?

  2. Linux下,gcc/g++出来的二进制可执行程序,默认是release模式

    • 在Linux下,使用常规的指令生成可执行程序为release模式,无法进行调试
    //常规生成
    gcc -o 可执行文件名 源代码文件
    g++ -o 可执行文件名 源代码文件
    
  3. 要使用gdb调试,必须在使用gcc/g++生成二进制程序时,加上-g选项

    gcc -o 可执行文件名 源代码文件 -g
    g++ -o 可执行文件名 源代码文件 -g
    

下面我们在如下test.c文件下编辑测试代码,进行测试
在这里插入图片描述
注意: 第7行代码,在for循环内定义变量i,这种写法是在c99中开始支持的,我使用的gcc/g++编辑器不支持这种写法,需要在执行命令后添加-std=c99

Makefile文件如下:
在这里插入图片描述
若不会使用Makefile文件,可直接使用如下两条指令测试

gcc -o MyTest-debug test.c -g -std=c99     //生成debug模式的可执行文件
gcc -o MyTest-release test.c -std=c99     //生成release模式的可执行文件

首先,测试release模式下,是否可以调试
在这里插入图片描述
如上图显示,红色框内,表示没有找到调试符号,无法进行调试。

其次,测试debug模式下,是否可以调试

在这里插入图片描述
没有显示错误信息,可以正常调试

最后: 观察两个可执行文件的体积,明显debug要大于release
在这里插入图片描述

拓展

我们可以使用readlef指令查看两个可执行文件下的信息,如下:

在这里插入图片描述
我们可以通过该指令,查看两个文件下的debug信息,如下(grep 指令为查找字符串指令):
在这里插入图片描述
MyTest-debug文件下找到了debug信息,MyTest-release什么都没有。

2.如何使用gdb调试

调试器的核心工作:定位问题

接下来简绍在Linux下如何使用gdb进行调试,该段落为分步骤讲解,将gdb下的命令总结放在了下一段落。
如果大家对gdb并不属性,按步骤操作即可

  1. 进入调试

    使用gdb file指令进入调试模式,如下图
    在这里插入图片描述

  2. 显示要调试的代码

    • l/list 行号:显示文件源代码,从输入的行号起,向下列出十行。一般我们在开始调试时,从l 1开始查看,接着输入lEnter键,即可获得上次查找位置往下的代码
      在这里插入图片描述
      注意: 输入gdb的指令后,Enter键就会记录。即,输入指令后,接着输Enter键会重复上面的动作。下面的指令也遵循这个规则。
    • 在刚进入gdb模式后,单独使用l进行查看,显示的代码为随机的
      在这里插入图片描述
  3. 设置断点

    • break/b 行号:在某一行设置断点

      如下图,在19行设置断点

    • break/b 函数名:在某个函数开头设置断点

      如下图,在addTestTop函数处设置断点

      在这里插入图片描述

      5是addTestTop函数内第一行代码的行号。

    • break/b 文件名:函数名:多文件时,可使用该方法设置断点

    • info break/b:查看断点信息

      在这里插入图片描述

      当程序运行后,会在断点处停下,在次查看断点,会显示在该断点处停下的次数。

      在这里插入图片描述

    注意: 在gdb中断点的序号是增长的,每次使用后会不断增长,直到关闭在开启后,重新从1开始

  4. 运行程序

    • r/run:运行程序

      • 有断点的情况,运行到断点处停止
        在这里插入图片描述
      • 无断点的情况,直接运行完 在这里插入图片描述
    • 注意: 一次运行是在全部main函数内全部代码运行完后结束,中途遇到断点停下后,进行其他查看指令不会影响此次调试

  5. 有断点,运行后,逐语句执行

    • s/step:遇到函数,进入函数内部

      在这里插入图片描述

    注意: 进入其他函数后,会产生调用链,即一个函数调用另一个函数,接着再去调用其他函数。

    可通过bt指令查看

    在这里插入图片描述

  6. 有断点,运行后,逐过程运行

    • n/next即遇到函数不进入函数,直接执行下一条指令

    在这里插入图片描述

    • 还记得上面说的按Enter键,执行上次执行的指令吗?如果需要调试的的内容过多,按一次sn后接着按Enter键即可
  7. 删除断点

    • delete/d breakpoints:删除所有断点

      在这里插入图片描述

    • delete/d n:删除序号为n的断点

      在这里插入图片描述

  8. 打开和关闭断点

    当我们不想使用一个断点,也不想删除该断点时使用

    • disable breakpoint 断点序号:关闭断点

      在这里插入图片描述

    • enable breakpoint 断点序号:打开断点

      在这里插入图片描述

  9. 查看变量

    • p 变量名:这个指令是需要查看的时候输入,不会影响调试,如下我在调试进入addTestTop函数后,执行了几段语句后,查看sum变量的结果,此时sum为6.

      在这里插入图片描述

    • 这样查看的效率太低,我们在VS中使用调试时,是执行一次相对应的变量随之变化,可以直接查看,该方法需要用户自己调用,不方便,我们可以使用以下的方法

  10. 跟踪查看变量

    • display 变量名:执行后,该变量在每执行一个语句后,都会显示出来

      在这里插入图片描述

    • 可以显示内置类型、结构体等自定义类型、stl

  11. 取消对断点的跟踪

    • undisplay 序号:不想跟踪某变量时使用

      在这里插入图片描述

  12. 跳转至指定行

    • until 行号:跳转至X行,在我们上面的代码中有一个循环,我们可以使用该指令跳转出循环
      在这里插入图片描述
  13. 将整个函数跑完

    • finash:进入一个函数后执行,只执行该函数,执行完后停下

    在这里插入图片描述

  14. 从一个断点,到下一个断点

    • continue/c:直接运行到下一个断点处

      在这里插入图片描述

    • util、finish、continue结合后,可实现基本的调试功能

  15. 退出gdb

    • q/quit:如果正在调试,会提示是否需要退出

    在这里插入图片描述

3.指令集

gdb binFile 退出: ctrl + dquit/q 调试命令:

  • list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
  • list/l 函数名:列出某个函数的源代码。
  • r或run:运行程序。
  • n 或 next:单条执行。
  • s或step:进入函数调用
  • break(b) 行号:在某一行设置断点
  • break 函数名:在某个函数开头设置断点
  • info break :查看断点信息。
  • finish:执行到当前函数返回,然后挺下来等待命令
  • print§:打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • 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

http://www.ppmy.cn/news/18732.html

相关文章

第23章_Tomcat和JavaEE入门

一、JavaEE简介什么是JavaEEJavaEE(Java Enterprise Edition),Java企业版,是一个用于企业级web开发平台。最早由Sun公司定制并发布,后由Oracle负责维护。JavaEE平台规范了在开发企业级web应用中的技术标准.在JavaEE平台…

树状数组的原理和区间和

目录 一、前言 二、树状数组的原理 1、杂论 2、从二叉树到树状数组 3、神奇的 lowbit(x) 操作 4、tree[ ]数组:将一维信息转换为树形信息存储 5、基于 tree[ ] 的计算 6、tree[]的更新(要加lowbit) 三、树状数组的应用 1、单点修改…

学人工智能电脑主机八大件配置选择指南

来源:深度之眼 作者:frank 编辑:学姐 本篇主要是帮助大家构建高性能、高性价比的AI开发的硬件平台。如何不把钱浪费到不必要的硬件上,并合理搭配硬件配置节省预算是本文想要去讨论的问题。如果预算充足,笔者建议购买一…

【计算机网络】HTTP/HTTPS

HTTP网络协议 虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一 理解网络协议 协议是一种 “约定”. socket api的接口, 在读写数据时, 都是按 “字符…

英语学习打卡day1

2023.1.19 重点单词 1.speculation n.推测,投机 speculate v. speculative adj. spectate v.看 spectator inspect 检查(往里看) aspect 外观(看一眼) prospect 前景 2.literally adv.(强调事实可能令人惊讶)真正…

学习wifi操作模块simplewifi的基本用法

之前学习Python的过程中学过基于pywifi模块操作wifi连接的用法,在dotnet中,SimpleWifi也支持类似的功能。SimpleWifi是C#语言编写的在Windows系统中管理wifi连接的库,它抽象并封装了Managed Wifi API中的wifi操作相关函数,更易于使…

VVDocumenter-Xcode github README.md 中英文翻译

2023-01-22 19:29PM Xcode 从版本 8 开始,直接使用快捷键即可生成注释文档。快捷键:optioncommand/ 最近在学习 Xcode 的使用,查到有一款用于生成注释文档的插件:VVDocumenter-Xcode 进入其 github 页面之后看 README&#xff0c…

Ajax面试题目

更多Ajax面试题目可以查看专栏内容 1.AJAX应用和传统Web应用有什么不同? 传统的web前端与后端的交互中,浏览器直接访问Tomcat的Servlet来获取数据。Servlet通过转发把数据发送给浏览器。当我们使用AJAX之后,浏览器是先把请求发送到XMLHttpR…