Linux基础(六):Linux 系统上 C 程序的编译与调试
本篇博客详细分析,Linux平台上C程序的编译过程与调试方法,这也是我们后续程序开发的基础。
目录
一、第一个hello world程序
1.1 创建.c文件
1.2 编译链接 + 运行可执行程序
二、编译链接过程
2.1 预编译阶段
2.2 编译阶段
2.3 汇编阶段
2.4 链接阶段
三、gcc 分步编译链接
3.1 一步完成编译链接生成可执行程序
3.2 分两步完成编译链接生成可执行程序
3.3 多文件编译链接
四、 make工具和makefile文件
4.1 什么是make和makefile
4.2 利用make工具完成上一小节的自动化编译过程
4.2.1 编写makefile文件
4.2.2 利用make工具自动生成可执行程序
4.2.3 总结
五、gdb 调试
5.1 Debug 版本和 Release 版本
5.2 单进程、单线程基础调试命令
5.3 使用GDB软件调试程序的基本步骤
5.4 如何在自动化编译工具中加入命令,自动生成含有调试信息的Debug版本
5.5 多进程调试命令
5.6 多线程调试命令
一、第一个hello world程序
1.1 创建.c文件

1.2 编译链接 + 运行可执行程序

C语言是一门编译型语言,编译型语言首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。对于编译型语言,绕不过的就是编译器。GCC(GNU编译器套件):GNU Compiler Collection。可以编译C、C++、JAVA、Fortran、Pascal、Object-C、Ada等语言。
gcc是GCC中的GNU C Compiler(C 编译器),g++是GCC中的GNU C++ Compiler(C++编译器)
注意:对于Linux平台下,生成的可执行程序没有后缀.exe ,关于编译链接的过程,我们下面作详细分析。
二、编译链接过程

2.1 预编译阶段
a) 删除所有的“#define”,并且展开所有的宏定义;
b) 处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;
c) 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置;
d) 删除所有的注释;
e) 添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;
f) 保留所有的#pragma 编译器指令,因为编译器需要使用它们。
2.2 编译阶段
词法分析、语法分析、语义分析,代码优化,汇总符号。
2.3 汇编阶段
将汇编指令翻译成二进制格式,生成各个 section,生成符号表。
2.4 链接阶段
a) 合并各个 section,调整 section 的起始位移和段大小,合并符号表,进行符号解析, 给符号分配虚拟地址
b) 符号重定位
三、gcc 分步编译链接
3.1 一步完成编译链接生成可执行程序
gcc -o main main.c
3.2 分两步完成编译链接生成可执行程序
step1、gcc -c main.c 生成main.o文件
step2、gcc -o main main.o 生成main(main.exe)可执行程序
3.3 多文件编译链接
创建3个源文件如下:add.c max.c main.c 


方式1:一步直接完成编译链接生成可执行程序

方式2:分两步;
- 首先,先把每个文件生成对应的.o文件, gcc -c xxx.c
- 其次,将所有的.o文件链接生成可执行程序文件main, gcc -o main main.o xx.o xx.o

四、 make工具和makefile文件
4.1 什么是make和makefile
当源码文件比较多的时候就不适合通过直接输入gcc命令来编译,这时候就需要一个自动化的编译工具, 这就是make工具,make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
- make:一般说GNU Make,是一个软件,用于将源代码文件编译为可执行的二进制文件,make工具主要用于完成自动化编译。make工具编译的时候需要Makefile文件提供编译文件。
- Makefile:make工具所使用的文件,Makefile指明了编译规则。makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
4.2 利用make工具完成上一小节的自动化编译过程
4.2.1 编写makefile文件

工程是需要被清理的,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
4.2.2 利用make工具自动生成可执行程序

4.2.3 总结
利用make工具完成自动化编译的大致步骤如下:
- 提供好所有的源文件.c和makefile文件
- 执行命令make, 自动生成编译链接四个阶段的所有文件
- 清理中间的目标文件,执行命令:make clean
五、gdb 调试
5.1 Debug 版本和 Release 版本
1、Debug 版本
Debug 版本为可调试版本,生成的可执行文件中包含调试需要的信息。我们作为开发人 员,最常用的就是 debug 版本的可执行文件。 Debug 版本的生成: 因为调试信息是在编译过程时加入到中间文件(.o)中的,所以必须在编译时控制其生成包含调试信息的中间文件。如:gcc -o hello hello.c -g
2、Release 版本
Release 版本为发行版本,是提供给用户使用的版本。用 gcc 默认生成的就是 Release 版 本。 因此,我们使用gdb进行调试 ,首先将源代码编译、链接生成 Debug 版本的可执行文件,然后通过‘gdb Debug 版本 的可执行文件名’进入调试模式。
5.2 单进程、单线程基础调试命令
| 命令 | 作用 |
| l | 显示代码,默认一次只显示10行 |
| b+行号 | 给指定行添加断点 |
| b+函数名 | 给指点函数的第一有效行添加一个断点 |
| info break | 显示断点信息 |
| delete +断点编号 | 删除指定断点 |
| r(run) | 运行程序,启动调试代码 |
| n(next) | 单步执行 |
| c (continue) | 继续执行,直接执行到下一个断点处 |
| s(step) | 进入将要被调用的函数中执行 |
| finish | 跳出函数 |
| p +变量 (print) | 打印变量的值 |
| p + &变量 | 打印变量的地址 |
| p arr(数组名) | 打印数组所有元素的值 |
| ptype + 变量 | 显示变量类型 |
| bt(breaktrace) | 显示函数调用栈 |
| q (quit) | 退出调试 |
- l +行号 就能跳转到该行。
- l +文件名:行号 能跳转文件 跳转别的文件的第几行 l add.c :1;
- 显示函数调用的栈关系 上边信息显示当前所在位置,下面信息显示执行完当前程序会回到哪一行。
5.3 使用GDB软件调试程序的基本步骤
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等 IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。调试程序的基本步骤如下:
- 生成包含调试信息的Debug版本,如:gcc -o test test.c -g
- 执行命令:gdb test
- 进入调试,利用常用的命令
5.4 如何在自动化编译工具中加入命令,自动生成含有调试信息的Debug版本


在前面定义一个 GDB=-g,在生成规则后加$(GDB),就会取GDB的值;不让生成debug版本就是把GDB置空(GDB=)。
5.5 多进程调试命令
(gdb)set follow-fork-mode mode
mode 可以选择 parent 或者 child,即:选择调试那个进程。 注意:未被跟踪调试的进程会直接执行结束。
5.6 多线程调试命令
a) 利用 info threads 查看线程信息;
b) thread id 调试目标 id 指定的线程;
c) set scheduler-locking off | on | step; “off”表示不锁定任何线程; “on”只有当前被调试的线程继续运行; “step”在单步执行的时候,只有当前线程会执行;
以上就是全部内容!请务必掌握,这是后续学习的基础,欢迎大家点赞加关注评论,您的支持是我前进最大的动力!下期再见!
相关文章:
Linux基础(六):Linux 系统上 C 程序的编译与调试
本篇博客详细分析,Linux平台上C程序的编译过程与调试方法,这也是我们后续程序开发的基础。 目录 一、第一个hello world程序 1.1 创建.c文件 1.2 编译链接 运行可执行程序 二、编译链接过程 2.1 预编译阶段 2.2 编译阶段 2.3 汇编阶段 2.4 链…...
移动硬盘难题:不显示容量与无法访问的解决策略
在使用移动硬盘的过程中,有时会遇到一些棘手的问题,比如移动硬盘不显示容量且无法访问。这种情况让人十分头疼,因为它不仅影响了数据的正常使用,还可能导致重要数据的丢失。接下来,我们就来详细探讨一下这个问题及其解…...
基于springboot+vue的智慧外贸平台
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
@Async详解,为什么生产环境不推荐直接使用@Async?
一、Async 注解介绍: Async 注解用于声明一个方法是异步的。当在方法上加上这个注解时,Spring 将会在一个新的线程中执行该方法,而不会阻塞原始线程。这对于需要进行一些异步操作的场景非常有用,比如在后台执行一些耗时的任务而不…...
LaTeX 2022软件安装教程(附软件下载地址)
软件简介: 软件【下载地址】获取方式见文末。注:推荐使用,更贴合此安装方法! LaTeX 2022是基于ΤΕΧ的一种排版系统,特别适用于生成科技和数学文档的高质量打印。它可用于各种文档类型,从简单信函到完整…...
纯干货分享 机器学习7大方面,30个硬核数据集
在刚刚开始学习算法的时候,大家有没有过这种感觉,最最重要的那必须是算法本身! 其实在一定程度上忽略了数据的重要性。 而事实上一定是,质量高的数据集可能是最重要的! 数据集在机器学习算法项目中具有非常关键的重…...
算法训练营day46
一、单词拆分 元素无重可复选 base case is.length return true,遍历到了最后, 因为ilen s.length,len初始值为1,那么i1 s.length,那么i s.lenth -1 也就是最后一个字符位置 dp(s,i)函数定义:返回 s[i…] 是否能够…...
推荐五个线上兼职,在家也能轻松日入百元,适合上班族和全职宝妈
在这个瞬息万变的时代,你是否也曾考虑过在繁忙的工作之外,寻找一份兼职副业来补贴家用,同时保持生活的多样性?别急,现在就让我为你揭秘五个可靠的日结线上兼职岗位,助你轻松迈向财务自由之路! 一…...
Python_文件操作_学习
目录 一、关于文件的打开和关闭 1. 文件的打开 2.文件的关闭 二、文件的读取 1. 文件的读_r 2. 使用readline 3.使用readlines 三、文件的写入 1. 文本的新建写入 2.文本的追加写入 四、文件的删除和重命名 1.文件的重命名 2.文件的删除 五、文件的定位读写 1.t…...
Leetcode 3154. Find Number of Ways to Reach the K-th Stair
Leetcode 3154. Find Number of Ways to Reach the K-th Stair 1. 解题思路2. 代码实现 题目链接:3154. Find Number of Ways to Reach the K-th Stair 1. 解题思路 这一题思路上就是一个动态规划,我们只需要确定一下运行的终止条件,然后写…...
Vue3/Vite引入EasyPlayer.js播放H265视频错误的问题
一、引入EasyPlayer.js github链接:GitHub - EasyDarwin/EasyPlayer.js: EasyPlayer.js H5播放器 将demo/html目录下的 EasyPlayer-element.min.js、EasyPlayer-lib.min.js、EasyPlayer.wasm、jquery.min.js 复制到vue3工程的public目录下,注意,vue3 vite的index.html文件…...
CentOS 7安装alertmanager
说明:本文介绍如何在CentOS 7安装alertmanager; Step1:下载安装包 访问Github仓库,下载对应版本的alertmanager安装包 https://github.com/prometheus/alertmanager/releases 如何查看自己系统的信息,可参考下图中的…...
YOLOv10详细解读 | 一文带你深入了解yolov10的创新点(附网络结构图 + 举例说明)
前言 Hello大家好,我是Snu77,继YOLOv9发布时间没有多久,YOLOv10就紧接着发布于2024.5.23号(不得不感叹YOLO系列的发展速度,但要纠正大家的观点就是不是最新的就一定最好)! 本文给大家带来的是…...
【openlayers系统学习】3.5colormap详解(颜色映射)
五、colormap详解(颜色映射) colormap 包是一个很好的实用程序库,用于创建颜色图。该库已作为项目的依赖项添加(1.7美化(设置style))。要导入它,请编辑 main.js 以包含以下行…...
Redis教程(十五):Redis的哨兵模式搭建
一、搭建Redis一主二从 分别复制三份Redis工作文件夹,里面内容一致 接着修改7002的配置文件,【redis.windows-service.conf】 port 7002 改成 port 7002 slaveof 127.0.0.1 7001 7003也同样修改 port 7003 slaveof 127.0.0.1 7001 这样就指定了700…...
【C语言】8.C语言操作符详解(3)
文章目录 10.操作符的属性:优先级、结合性10.1 优先级10.2 结合性 11.表达式求值11.1 整型提升11.2 算术转换11.3 问题表达式解析11.3.1 表达式111.3.2 表达式211.3.3 表达式311.3.4 表达式411.3.5 表达式5: 11.4 总结 10.操作符的属性:优先级、结合性 …...
离线初始化k8s
导出和导入所有必要的 Kubernetes 镜像,使用阿里云作为源。 在能访问外网的机器上拉取镜像 首先,在有外网访问的机器上运行以下命令来拉取所有 Kubernetes v1.29.5 版本需要的镜像: kubeadm config images pull --image-repository regist…...
C++字符编码 cppp-reiconv库使用详解
经常写一些控制台小程序,常常会遇到输出中文乱码的问题,在windwos下可以使用MultiByteToWideChar转换字符编码,但跨平台就需要cppp-reiconv这样的第三方字符编码处理库,且开源。 一、下载cppp-reiconv库的源码和静/动态库 GitHu…...
通过继承React.Component创建React组件-5
在React中,V16版本之前有三种方式创建组件(createClass() 被删除了),之后只有两种方式创建组件。这两种方式的组件创建方式效果基本相同,但还是有一些区别,这两种方法在体如下: 本节先了解下用extnds Reac…...
PgSQL内核机制 - 算子执行统计元组个数
PgSQL内核机制 - 算子执行统计元组个数 我们在执行explain analyze观察执行计划执行情况时,时常通过每个算子实际执行结果来分析SQL的执行,其中有一项“rows XXX”表示执行的行数(这里姑且先认为是执行的真实行数)。但有些场景下…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
