Linux下的gcc与gdb

ops/2024/9/20 1:09:02/ 标签: 开发语言, linux, c语言

目录

Linux下的gcc与gdb

代码编译与链接

函数库

gdb介绍和安装

gdb基本使用指令

示例代码

debug模式和release模式

基本指令

进入gdb调试与显示调试代码

创建断点与删除断点

启用和禁用断点

执行代码

逐语句和逐过程调试

断点跳转

显示指定变量以及对应内容

打印变量的值

执行到指定行

执行完当前作用域的代码

监视变量

运行时临时修改变量内容

条件断点

退出gdb调试

cgdb增强调试过程


Linux下的gcc与gdb

在前面C语言的编译与链接章节中学到了C语言的可执行程序是如何从代码一步一步生成的,下面是前面用到的指令

代码编译与链接

代码编译预处理

gcc -E test.c -o test.i
  • 选项-E,该选项的作用是让gcc在预处理结束后停止编译过程
  • 选项-o是指目标文件,.i文件为已经过预处理的C原始程序

预处理生成汇编

gcc -S test.c -o test.s
如果已经在前面执行了编译预处理生成了 test.i文件,则可以直接用 test.i文件而不是 test.c文件
  • 用户可以使用-S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码

汇编生成二进制文件

gcc -c test.c -o test.o
如果已经在前面执行了编译预处理生成了 test.s文件,则可以直接用 test.s文件而不是 test.c文件
  • 使用选项-c就可看到汇编代码已转化为.o的二进制目标代码,.o文件也被称为可重定位目标文件

二进制文件链接生成可执行程序

gcc test.c -o test
如果已经在前面执行了编译预处理生成了 test.o文件,则可以直接用 test.o文件而不是 test.c文件

函数库

函数库一般分为静态库和动态库两种

  1. 静态库:编译链接时把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,在运行时不再需要库文件了。其后缀名一般为.a
  2. 动态库:在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为.sogcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件

直接编译时选择动态库:gcc test.c -o test

使用静态编译选项-static时选择静态库:gcc -o test test.c -static

gdb介绍和安装

gdb(GNU调试器)是GNU项目的一部分,用于调试C、C++、Pascal、Objective-C、Ada以及其他语言编写的程序。它允许开发者执行一系列的调试操作,如启动程序、设置断点、监视变量、单步执行代码、改变程序状态等,以便于找出并修正程序中的错误

在CentOS安装gdb可以使用下面的指令:

sudo yum install -y gdb

需要查看gdb版本时可以使用下面的命令:

gdb --version

gdb基本使用指令

示例代码

以下面的代码作为本次的调试用例:

#include <stdio.h>int add(int start, int end) {int sum = 0;for(int i = start; i <= end; i++) {sum += i;}return sum;
}int main() {printf("Start programme\n");int start = 0;int end = 20;int result = add(start, end);printf("result = %d\n", result);printf("End programme\n");return 0;
}

对应的Makefile文件内容如下:

TARGET=test
SRC=test.c$(TARGET):$(SRC)$(CC) -o $@ $^ -std=gnu99.PHONY:clean
clean:rm -rf test

debug模式和release模式

默认情况下,直接使用gcc编译生成的可执行程序是release模式下的程序,不包含任何debug调试信息,并且release模式下无法进行调试。如果需要使用gcc编译生成的可执行程序是debug模式下的程序,就需要带上-g选项,生成的可执行文件包含debug信息,并且debug模式可以对代码进行调试

在CentOS下可以使用下面的指令判断一个文件是否使用debug模式编译生成

readelf -S test | grep -i debug

在Ubuntu下直接使用file+可执行程序文件即可查看到是否带有debug的字段即可判断是否使用debug模式编译生成

使用初始的Makefile进行编译时,生成的是release模式下的可执行程序,所以不带有任何debug信息:

而将Makefile中的内容修改为如下:

# ...
$(TARGET):$(SRC)$(CC) -o $@ $^ -std=gnu99 -g
# ...

此时就会显示debug相关字段的信息

基本指令

进入gdb调试与显示调试代码

在创建出debug模式下的可执行程序test后,在终端输入gdb test,即可进入调试模式

在调试中,输入l+对应数字显示指定行以及之前的代码,默认一共显示10行代码,而l后方的数字对应行的代码一般会出现在展示的10行代码中央

如果输入 l 0则默认从第一行代码展示,一共展示10行,效果同 l 1。另外, gdb中存在指令记忆,不输入任何指令会默认执行上一条指令

技巧:在gdb调试过程中,如果想要看到文件中的完整代码,可以输入l 0或者l 1,在展示完10行代码后接着按回车即可继续展示后10行代码,以此类推直到抵达文件内容末尾。

也可以使用l+文件:数字显示指定文件中的对应行相应代码,其余效果与l+数字相同

创建断点与删除断点

gdb中,使用b/break+需要添加断点的行号即可在指定行添加断点

需要查看已经添加断点可以使用info + b,显示的表格即为已经添加的断点信息

gdb中的断点都拥有自己的编号,删除断点时使用del + 断点编号

需要注意,编号的大小依次递增,并且其编号生命周期随着 gdb结束而结束,所以尽管删除断点,删除断点的编号依旧不会被新的断点使用

例如,在代码的16行和20行创建断点,展示断点信息,再删除20行的断点,再在第5行添加断点

  • 创建断点

  • 删除断点和添加新断点

同样,也可以使用break 文件:行号指定文件名中的行位置创建断点,还可以指定函数名b+函数名添加断点,函数名断点会默认跳到函数的第一条语句

启用和禁用断点

gdb中,使用enable+断点编号启动对应行的断点,使用disable+断点编号禁用断点

  • 对于启用的断点来说,使用info b查看断点信息可以在Enb列看到其值为y(代表yes
  • 对于禁用的断点来说,使用info b查看断点信息可以在Enb列看到其值为n(代表no

例如,禁用第5行的断点,再启用

  • 初始状态

  • 禁用状态

  • 启用状态

执行代码

使用r指令运行代码

默认情况下,使用r指令运行代码会直接显示代码运行结果

如果添加了断点,使用r指令运行代码时,会直接运行到断点所在行然后等待(前面的代码会执行,但是断点所在行不会执行),此时会显示当前运行所在行

如果代码已经处于运行状态,再使用r指令会收到提示是否重新运行,按照需求选择即可

例如,在第17行添加断点,执行代码

逐语句和逐过程调试

gdb中,使用n指令进行逐过程调试,在逐过程中,不会执行函数细节,即遇到函数不会进入函数;使用s指令进行逐语句调试,与逐过程相反,在逐语句中,会执行函数细节,但是不会执行库中的函数

逐语句和逐过程调试过程中,显示的行是下一步需要执行的行,而不是已经执行之后的行

逐语句和逐过程不会在多个断点间跳转
断点跳转

gdb中,如果创建了多个断点需要直接从一个断点跳到下一个断点位置并执行两个断点间的代码,可以使用c指令

例如,在第17行和第5行创建两个断点,使用指令从第17行的断点跳转到第5行的断点

显示指定变量以及对应内容

gdb中,使用display + 变量名可以显示指定变量的值,显示的变量会在每一次调试语句中显示对应的内容,显示的变量会一直持续显示除非离开变量所在作用域、显式取消显示或者退出gdb

显示变量必须在对应变量所在作用域,否则会报错为: No symbol "xxx" in current context
需要查看变量的地址,也可以使用 display+&变量名

每一个变量也存在变量,并且变量编号不受作用域的限制,并且也满足线性递增,所以取消显示已经显示的变量,使用undisplay + 变量编号

打印变量的值

使用p+变量名指令可以打印对应变量的值

执行到指定行

gdb中,可以使用until+行号直接跳转到对应行,并且执行起始位置和指定行位置之前的代码。如果until中指定行的代码执行完毕之后没有遇到断点,程序就会直接运行到当前作用域结束,否则跳转到下一个断点处

执行完当前作用域的代码

如果需要快速执行完当前函数作用域(非最外层函数作用域,本示例代码中最外层函数作用域为main函数所在作用域,非最外层函数作用域为add函数所在作用域)的代码,则可以使用finish指令

对长的代码块进行区间调试技巧:将断点打在多个函数所在行,使用断点+finish/until+c依次检查函数是否出现问题
监视变量

所谓监视变量,与前面打印变量的值基本一样,但是不同的是,监视变量在gdb中本质是打一个断点,并且只有在变量的值发生变化时,才会再次自动打印变量以及对应的值

监视变量使用watch+变量名,删除监视变量与删除断点的方式相同,也可以在断点列表中查看到对应的监视变量断点

运行时临时修改变量内容

部分情况下问题已经暴露并且需要改变一下变量内容临时查看是否修改对应变量的内容可以解决问题,此时就可以使用set 变量名=值在调试代码时临时改变指定变量的值

条件断点

gdb中,一共有两种添加条件断点的方式:

  1. 在指定位置新增条件断点:使用b/break+断点行号+if 条件
  2. 在已有断点位置添加条件:使用condition+已有断点编号+条件
条件断点在新增后,会在断点列表显示断点跳转条件

退出gdb调试

使用quit指令退出调试,如果调试的代码还在运行,会询问用户是否结束并退出调试,根据需要选择即可

cgdb增强调试过程

直接使用gdb调试需要一直使用指令查看代码以及断点,为了使调试更加方便,可以使用cgdb代替gdb,但是基本使用方式与gdb完全相同,只是cgdb视觉上更加直观

在CentOS下,使用下面的指令安装cgdb

sudo yum install -y cgdb

使用cgdb调试代码就可以看到下面的界面:

代码行号处的箭头表示下一步需要执行的代码,刚开始并未没有断点或未开始情况下,会指向main函数的第一条语句

如果添加了断点,则断点所在行号会变成红色,例如下面的结果:

尽量不要使用鼠标滚轮拖动代码窗口,防止出现问题


http://www.ppmy.cn/ops/110910.html

相关文章

代码随想录算法day30 | 动态规划算法part03 | 01背包问题 二维 ,01背包问题 一维,416. 分割等和子集

正式开始背包问题&#xff0c;背包问题还是挺难的&#xff0c;虽然大家可能看了很多背包问题模板代码&#xff0c;感觉挺简单&#xff0c;但基本理解的都不够深入。 背包问题&#xff0c;力扣上没有原题&#xff0c;题目是在卡码网找的 动态规划&#xff1a;01背包理论基础 本…

简单易懂的方式来解释机器学习(ML)和深度学习(DL)的区别与联系

让我们从多个角度出发&#xff0c;用一些简单易懂的方式来解释机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09;的区别与联系。 1. 概念上的区别 机器学习 想象一下你在教一个小孩子如何分辨猫和狗。你可能会给这个孩子看很多猫和狗的照片&#xff…

Unity-Time类

目录 Time.timeScale Time.deltaTime Time.unscaledDeltaTime Time.time Time.frameCount Time.fixedDeltaTime Time.timeScale 时间缩放比例 时间停止 Time.timeScale 0; //回复正常 //Time.timeScale 1; //2倍速 …

VSCode 离线安装中文语言包

1.插件市场 Extensions for Visual Studio family of products | Visual Studio Marketplace 输入&#xff1a; language 在version history里面下载相应的版本&#xff0c;若没有就下载最新的 在下面安装 安装完重启就可以了。 可能会提示的失败&#xff1a; Unable to ins…

【vscode】 快速生成react组件

在VSCode中快速生成React组件的方法主要包括使用内置的代码片段和安装第三方插件。以下是具体的步骤和方法&#xff1a; 使用内置代码片段‌ VSCode支持用户自定义代码片段&#xff0c;你可以通过输入特定的前缀&#xff0c;然后按下Tab键&#xff0c;来快速生成React组件的基…

Cenos7镜像+Docker问题

前言 好用的镜像 阿里 curl -o /etc/yum.repos.d/Centos7-aliyun.repo https://mirrors.wlnmp.com/centos/Centos7-aliyun-x86_64.repo科大 curl -o /etc/yum.repos.d/Centos7-ustc.repo https://mirrors.wlnmp.com/centos/Centos7-ustc-x86_64.repo网易 curl -o /etc/yum…

概率论原理精解【14】

文章目录 拓扑空间拓扑空间映射一、连续映射二、同胚映射三、开映射与闭映射四、其他映射五、映射空间 第一可数空间第一可数性公理第一可数空间的性质例子与反例 邻域基定义性质例子应用 参考文献 拓扑空间 拓扑空间映射 是一个相当宽泛且复杂的话题&#xff0c;因为拓扑空间…

HW蓝队某知名大厂面试题分享

&#x1f91f; 基于入门网络安全/黑客打造的资源包无偿分享中&#xff1a; &#x1f449;黑客&网络安全入门&进阶学习资源包 应急响应流程 1&#xff09;首先判断服务器资产、影响范围以及严重程度&#xff0c;确认有没有必要将服务器下线隔离&#xff0c;然后根据服务…

基于python+django+mysql+Nanodet检测模型的水稻虫害检测系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

第158天:安全开发-Python-Socket编程反弹Shell分离免杀端口探针域名爆破

前置知识 使用 socket 模块 1. 导入模块 首先&#xff0c;你需要导入 Python 的 socket 模块。 import socket 2. 创建套接字 使用 socket.socket() 函数创建一个新的套接字。这个函数可以接收两个参数&#xff1a;地址族和套接字类型。 地址族&#xff08;Address Family&…

筑牢网络安全防线:为数字时代保驾护航

《筑牢网络安全防线&#xff1a;为数字时代保驾护航》 一、网络安全&#xff1a;数字时代的关键课题 网络安全在当今数字时代的重要性愈发凸显。2024 年国家网络安全宣传周以 “网络安全为人民&#xff0c;网络安全靠人民” 为主题&#xff0c;深刻体现了网络安全与每个人息息…

OpenGL(四) 纹理贴图

几何模型&材质&纹理 渲染一个物体需要&#xff1a; 几何模型&#xff1a;决定了物体的形状材质&#xff1a;绝对了当灯光照到上面时的作用效果纹理&#xff1a;决定了物体的外观 纹理对象 纹理有2D的&#xff0c;有3D的。2D图像就是一张图片&#xff0c;3D图像是在…

MyBatis 如何将 Mapper 接口与其 XML 映射文件关联:深入原理与实现

MyBatis 如何将 Mapper 接口与其 XML 映射文件关联&#xff1a;深入原理与实现 1. 概述 MyBatis 是一个简单、灵活的持久层框架&#xff0c;它通过 SQL 语句将 Java 对象与数据库进行映射。MyBatis 支持基于 XML 和注解的配置方式。在实际开发中&#xff0c;XML 映射文件与 M…

云服务与虚拟主机:数字时代的网络托管选择

当今数字化的时代&#xff0c;无论是个人博主、小型企业还是大型企业&#xff0c;都需要一个可靠的网络托管解决方案来展示自己的网站或应用程序。云服务和虚拟主机是两种常见的选择&#xff0c;它们各有特点&#xff0c;适用于不同的需求。 一、虚拟主机 虚拟主机&#xff0…

SpringBoot闲一品交易平台

SpringBoot闲一品交易平台 #vue项目实战 #计算机项目 #java项目 SpringBoot闲一品交易平台通过运用软件工程原理和开发方法&#xff0c;借助Spring Boot框架&#xff0c;旨在实现零食交易信息的高效管理&#xff0c;提升用户的购物体验和满意度。 技术栈 开发语言&#xff1a;…

想了解医疗大模型吗?请看《智能系统学报》实验室最新综述论文

本文改编自实验室的最新综述论文《医疗领域的大型语言模型综述》&#xff0c;该论文发表于《智能系统学报》。《智能系统学报》是中国人工智能学会会刊、“中国人工智能学会推荐中文学术期刊”列表中的A类期刊。该论文合作单位包括上海理工大学、上海儿童医学中心、复旦大学附属…

文件存储阿里云

1.图片存储 图片存储是指将图片文件保存在服务器或云存储中的技术或服务。图片存储的主要目的是方便用户上传、存储、管理和分享图片文件。 图片存储可以分为两种主要类型&#xff1a;本地存储和云存储。 本地存储是将图片文件保存在本地服务器或计算机上的一种方式。这种存…

服务网关Gateway快速入门

1.引入 网关可以把它理解成坐高铁时的安检&#xff0c;他可以对用户做身份验证&#xff0c;哪些人能通过&#xff0c;哪些人不能通过&#xff0c;都由他决定&#xff0c;如果没有安检&#xff0c;那么高铁的安全性将受到打击&#xff0c;一个微服务没有网关&#xff0c;那么接口…

使用Docker快速启动Nacos集群

Nacos 是一个易于使用的平台&#xff0c;用于动态服务发现、配置管理和服务管理。它帮助您在云环境中快速构建云原生应用程序&#xff0c;支持服务的注册与发现、动态配置更新等功能。在本文中&#xff0c;我们将介绍如何使用 Docker 快速启动 Nacos 集群。 为什么使用 Docker…

美国税收制度及SAP实施

1. 税制综述 美国是以直接税为主的国家,实行联邦、州和地方&#xff08;市、县&#xff09;三级征税制度&#xff0c;属于彻底的分税制国家。美国联邦税以个人所得税和企业所得税为其主要收入来源&#xff0c;州税以销售与使用税为其主要收入来源&#xff0c;地方税以财产税为…