【Linux】-----工具篇(编译器gcc/g++,调试器gdb)

news2025/4/8 8:37:48

目录

一、gcc/g++

简单认识

程序的翻译过程认识gcc

预处理(宏替换)

编译

汇编

链接

宏观认识

如何理解(核心)

什么是链接?

链接的分类

二、gdb

基本的认识

基本操作及指令

安装gdb

启动gdb

​编辑 显示源代码(list)

运行程序(r)

断点 (b)

设置断点(b)

查看断点信息 (i)

删除断点 (d)

使能(打开/关闭)断点

逐过程(n)

逐语句(s)

打印变量&&地址(p)

变量/地址的常显示 

修改变量

转至下一断点(c)

结束函数

转至指定行 

查看栈帧


一、gcc/g++

简单认识

  • gcc:用于编译C语言的编译器
  • g++:用于编译C++的编译器,同时兼容编译C代码

程序的翻译过程认识gcc

预处理(宏替换)

作用:完成宏定义,头文件的展开,去注释以及条件编译等。

gcc指令:gcc -E xxx.c -o xxx.i

解释一下:

-E:让gcc在预处理后停止编译过程

-o:☞生成目标文件,

.i”后缀的文件是经过预处理的原始C程序

演示:

看看里面的内容:

vim test.i看看

可以看到代码代码量达到惊人的八百多行,实际上头文件的展开占大部分。。

 头文件的展开

实际上就是将系统中对应头文件的内容拷贝到源代码中,Linux系统的头文件一般都在/usr/include目录下,这些头文件在安装gcc或者其他编译器时都会安装到系统中,因此不需要我们自己去配置。

可以看到该目录下存在一大批头文件。。。。头文件的展开就是将这里内容拷贝到你的源代码中。所以说头文件在预处理后就没有用处了。

条件编译

场景:

在下载一些编译器时,都会发现存在一个社区版和一个专业版,比如window系统的vscode集成开发环境以及java的IDE等。两者区别就是:社区版是免费的但功能没有专业版齐全,专业版收费但功能齐全。但是呢大家有没有想过这样的一个问题,这样的集成开发环境的代码需要维护几份?实际上是一份,如果是两份的话,万一社区版出现问题,修正BUG的同时也要去修正专业版的BUG,十分的麻烦。所以实际中都是采用条件编译的方式去维护一份代码,因为条件编译的用处就是可以完成对代码的动态裁剪工作!

演示:

 运行结果:

我们再来看看预处理阶段代码的变化:

可以看到预处理后只剩下有指定v1宏定义的那段代码了,完成了裁剪工作,所以这样采用条件编译的代码维护起来就十分的方便,仅仅只需要维护这一份代码。

对于这样的条件编译,每次都需要打开代码,在定义宏,这样很麻烦,gcc存在命令行定义宏的方式。就是带上-D选项

 指令:gcc/g++  -D宏 源代码文件

举例:

注意:g++也是一样的方法!!!!

编译

作用:gcc/g++会检查代码的规范性、是否有语法错误等,无误后,把预处理阶段生成的“.i”代码翻译成汇编语言。

指令:gcc -S xxx.i -o xxx.s

举例:

-S:只进行编译,编译完成后就停止,生成汇编代码

注意:指令后面加上-std=c99是因为小编的gcc是4.x的老版本,没有更新,有的语法不支持。加上后就支持了,如果是g++,就加上-std=c++11,当然最新的编译器就不需要加。

看看test.s

汇编

作用:把编译阶段生成的“.s”汇编代码翻译成二进制目标文件,“.o”后缀,即机器可识别的代码

指令:gcc -c xxx.s -o xxx.o

演示:

打开看看

看不懂吧!我也看不懂,机器懂就行!

链接

宏观认识

该阶段的主要作用:将汇编生成的二进制代码翻译生成可执行文件".exe"。

指令:gcc xxx.o -o xxx.exe

演示:

如何理解(核心)
什么是链接?

实际上就是程序和库的结合并生成可执行程序,每一种编程语言都会有自己的标准库,这些库里面包含大量的头文件,以便开发者使用,能极大的提高开发的效率。

来看看上面的可执行程序的链接:

指令:ldd 可执行程序

值得一提的是函数库/标准库

实际上函数库分为动态库(.so为后缀)和静态库(.a为后缀)两种,在库里面都存在着对应函数的定义/方法。

实例:

我们都知道声明函数的同时也应该去实现该函数,但在c程序中我们所使用的“printf”函数,我们包含的头文件“stdio.h”仅仅只是函数的声明而并没有实现printf定义,程序也能运行,那是在哪里实现的定义?

实际上系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函 数“printf”了,而这也就是链接的作用。
链接的分类

分为动态链接和静态链接两种。

  • 动态链接

就是能够链接到动态库的链接。编译期间就知道动态库的地址,程序执行时,会根据链接文件链接到相应的动态库中,并找到相应的方法去执行,在返回结果。

优点:节省空间!

缺点:动态库不能丢失,一旦动态库缺失,所有的动态链接这个库的程序,都无法执行!

  • 静态链接

 程序在编译的时候,把静态库(.a)中的方法拷贝到自己的可执行程序中。

优点:不关心任何的库文件,即使你库文件丢失了,我也没有影响!

缺点:浪费资源,开销大。

演示看看:

可以看到静态链接的方式生成的可执行文件大小是很大的,十分的占空间,就是因为将静态库中的方法拷贝到可执行程序下了。一般情况下,Linux都不会安装有静态库,我们也没有必要去安装,小编仅仅是为了演示演示。

所以,实际上gcc在编译时默认都是使用动态库的,默认生成的都是动态链接!!

注意:上述操作都是在演示gcc,是因为gcc/g++的操作都大差不差。

二、gdb

基本的认识

编译器实际上都是有两种模式的:debug和release模式,

  • debug模式

 debug模式是可以被调试的,因为编译器形成可执行程序的时候会给可执行程序添加调试信息。因此该模式下的文件大小会比release模式的大。。

  • release模式

 release模式是不可以调试的,同时该模式下的代码优化程度高,也是给用户使用的版本。

值得注意的是:在Linux系统下,gcc/g++默认编译出的可执行程序都是release模式的。所以要想让其编译出debug模式,需要带上-g选项。

测试:

可以看到debug模式下的可执行程序的大小比release模式的大。。。。

基本操作及指令

安装gdb

sudo yum -y install gdb

启动gdb

  • 指令:gdb  debug模式下的可执行程序

 显示源代码(list)

  • 指令1list 或者l/ 行号,默认显示十行,同时gdb会记住最近的一次命令,所以可以按回车键继续显示

会发现并没有全部的显示,因为是从第七行开始的,所以我们可以输入list/l +0 从头显示

  • 指令2:list/l  函数名,列出某个函数的源代码!

  • 指令3:显示指定文件的源代码:list/l  文件名:行号/函数

运行程序(r)

  • 指令:r/run

使用这个指令,只是单单的运行程序而已,没有调试,类似于VS按下F5,需要配合断点使用!

断点 (b)

设置断点(b)
  • 指令1:b 行号,在某一行设置断点 
  • 指令2:b 函数,在某个函数的入口设置断点

 

查看断点信息 (i)
  •  指令:info(i)  b

重要参数解释:

Num:代表断点的编号

Type:断点类型

Enb:断点使能,y代表可用,n代表禁用。禁用不是删除!!

删除断点 (d)
  • 指令:delete(d) 断点编号

 注意:这里用的是断点的编号,而不是行号!!!行号是无法执行的!如果没有指明断点编号,也就是只是输入d,那就会自动将所有的断点都删除。

使能(打开/关闭)断点
  • 关闭指令:disable 断点编号

  • 打开指令:enable 断点编号

注意:和删除断点一样,如果没有指明断点编号,默认就是全部的断点关闭或者打开!!

逐过程(n)

  • 指令:next/n,类似VS的F10 

逐语句(s)

  • 指令:step/s ,类似VSF11。可以进入函数内部

打印变量&&地址(p)

  • 指令:print/p  变量/地址

这样比较麻烦,需要手动打开。。。。

变量/地址的常显示 

  • 打开指令:display  变量/地址 

 

注意:display也是有编号的!!为的就是关闭常显示!!

  •  关闭指令:undisplay  number(编号)

 

修改变量

  • 指令:set  var 变量名=值

注意:一旦使用这条指令,那结果肯定不一样了,因为改的是内存级别的值!!

转至下一断点(c)

  •  指令:continue/c

直接跳过中间的过程,运行至下一个断点处!!!

结束函数

  • 指令:finish

当我们进入函数内部,但不想一步步看问题时,可以采用这条指令,一次性运行完该函数,并给出最终结果!

转至指定行 

  • 指令:until  行号 

注意:使用该指令时,中间的程序都是运行了的!

演示一波:

查看栈帧

  • 指令:bt

这条指令可以看到函数调用入栈的过程!!!

说两句

可以看到在Linux下使用gdb调试对于小量代码来说还说得过去,量大时就十分的难受了。。所以实际上我们基本都是图形化界面,因为我们更喜欢图像化界面的调试,方便。。简明。。但是学习底层gdb还是十分的有用的,因为一些集成开发环境都是gdb套了层壳!!!!!


好了,本次内容就分享到这,如果对你有帮助,欢迎三连,你的鼓励就是我前进的动力!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1953558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网友提问:桌面与web开发哪个难度更大?

关于桌面应用开发与Web开发哪个难度更大的问题,实际上并没有绝对的答案,因为这取决于具体的开发任务、所使用的工具和技术栈等因素。不过,我们可以从几个方面来进行比较: 技术栈 Web开发: 前端通常涉及到HTML、CSS、J…

Ansible之playbook剧本编写(二)

tags 模块 可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。 playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个t…

全球奈拉滨市场规模预测:未来六年年复合增长率CAGR为1.1%

据恒州诚思研究,2023年全球奈拉滨市场规模大约为3.8亿元,预计未来六年年复合增长率CAGR为1.1%,到2030年市场规模将接近4.2亿元。这一增长反映了奈拉滨在全球医药行业中的重要性及其在未来发展中的潜在机会。随着科学的进一步发展和市场的扩展…

中小学汉字听写大赛方案及执行流程

一、活动背景 汉字作为中国最宝贵的文化遗产,在五千年的历史长河里,汉字以其浩瀚广博抒写着华夏历史,以其灵秀展示着炎黄之精神。传承汉字文明是我们的使命和主责任。为提高我校七年级学生听写汉字的能力,规范汉字书写的能力&…

ESD防护之电容妙用

谈到ESD防护,应用最广泛的是ESD/TVS管,对于正负4KV的pin脚不上电ESD测试,也可以仅仅依靠nf级电容完成ESD防护。下面以一篇实际案例进行说明。 实验要求:正负4KV对产品connector的Pin脚进行ESD测试,connector中的地脚接…

idea启动项目报:the command line via JAR manifest or via a classpath file and rerun.

解决方案 1.打开Edit Configurations,进去编辑,如下: 笔记配置 2.选择Modfiy options,点击Shorten command line 3.在新增的Shorten command line选项中选择JAR manifest或classpath file 4.点击保存后即可

企业如何通过红酒传达品牌理念?

在繁忙的商业世界中,品牌理念的传达往往是企业成功的关键。而红酒,这一优雅的饮品,不仅具有深厚的文化底蕴,更是品牌理念传递的很好载体。今天,我们就来探讨一下企业如何通过定制红酒——特别是洒派红酒(Bo…

Java漏洞复现(ctfshow279-297)strust 漏洞复现及原理解释

Java漏洞复现 Strust原理 JavaEE--------Struts2框架-CSDN博客 Web279 struts2漏洞 S2-001是当用户提交表单数据且验证失败时,服务器使用OGNL表达式解析用户先前提交的参数值,%{value}并重新填充相应的表单数据。 这里的%{value}简单理解就是和flask的…

【计算机网络】IP分片实验

一:实验目的 1:理解IP数据报分片的工作原理。 2:理解IP协议报文类型和格式。 二:实验仪器设备及软件 硬件:RCMS-C服务器、网线、Windows 2019/2003操作系统的计算机等。 软件:记事本、WireShark、Chrom…

昇思25天学习打卡营第22天|CycleGAN图像风格迁移互换

相关知识 CycleGAN 循环生成网络,实现了在没有配对示例的情况下将图像从源域X转换到目标域Y的方法,应用于域迁移,也就是图像风格迁移。上章介绍了可以完成图像翻译任务的Pix2Pix,但是Pix2Pix的数据必须是成对的。CycleGAN中只需…

DosSnake-入土为安第八天

记录一下不能F5反编译 加密方式 密文 异或操作函数 xor_string_with_key: 接受两个字符串作为输入:待处理的 text 和 key。对每个字符进行异或操作。使用 ord(char) 获取字符的 ASCII 值,ord(key[i % key_length]) 是 key 中对应位置的字符的…

3D Web轻量化引擎HOOPS Communicator针对复杂大模型Web端可视化的解决方案

随着工程设计、制造和建筑领域中三维模型的日益复杂化,如何在Web端高效处理和展示这些大规模数据成为一大挑战。HOOPS Communicator作为一款强大的3D可视化工具,提供了一套针对复杂大模型的轻量化解决方案,涵盖了模型轻量化及格式转换、超大模…

【基础算法总结】队列 + 宽搜(BFS)

队列 宽搜BFS 1.N 叉树的层序遍历2.二叉树的锯齿形层序遍历3.二叉树最大宽度4.在每个树行中找最大值 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&#…

活动报名小程序

#活动报名工具# # 活动报名小程序 ## 项目简介 一款通用的活动报名工具,包含活动展示,微信支付,订单管理,分享评价等功能。 品客聚精彩,有你才精彩!不只有线下活动还可以进行线上裂变活动。 …

SpringBoot知识笔记

一、基本概念 1.1 特性 起步依赖 自动配置 其它特性:内嵌的Tomcat、Jetty(无需部署WAR文件),外部配置,不需要XML配置(properties/yml)。 1.2 配置文件 SpringBoot提供了多种属性配置方式 //application.properties server.port=9090 server.servlet.context-path…

自从与泰勒斯威夫特约会以来,特拉维斯凯尔西表现得像布拉德皮特一样挥霍打扮

今年对于泰勒斯威夫特和特拉维斯凯尔西来说可谓是风云变幻的一年,他们秘密开始约会,然后有了今年最引人瞩目的恋情。对于这位 NFL 运动员来说,这是一个巨大的变化,因为随着斯威夫特的粉丝们了解了凯尔西家族的一切,他的…

人机交互不仅仅是科技问题

人机交互不仅仅局限于物理和数理科学的应用,还涉及到更广泛的管理、文理、哲学、艺术、伦理以及法律等领域。下面这些领域在人机协同和智能系统应用中扮演着重要角色: 智能系统在企业管理、资源分配、决策支持等方面的应用,可以帮助管理者优化…

自学网络安全,从小白到大神的破茧之路!

在当今数字化高速发展的时代,网络安全已经成为了至关重要的领域。无论是个人的隐私保护,还是企业、国家的关键信息资产维护,都离不开网络安全的有力保障。出于对这一领域的浓厚兴趣以及对未来职业发展的清晰规划,我毅然决然地踏上…

基于物联网的区块链算力网络,IGP/BGP协议

目录 基于物联网的区块链算力网络 IGP/BGP协议 IGP(内部网关协议) BGP(边界网关协议) 内部使用ISP的外部使用BGP的原因 一、网络规模和复杂性 二、路由协议的特性 三、满足业务需求 四、结论 基于物联网的区块链算力网络 通 过 多个物联网传感器将本地计算…

科普文:kubernets原理

kubernetes 已经成为容器编排领域的王者,它是基于容器的集群编排引擎,具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。 本文将带着大家快速了解 kubernetes ,了解我们谈论 kubernetes 都是在谈论什么。 一、背…