当前位置: 首页 > news >正文

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:分两步;

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

四、 make工具和makefile文件

4.1 什么是make和makefile

       当源码文件比较多的时候就不适合通过直接输入gcc命令来编译,这时候就需要一个自动化的编译工具, 这就是make工具,make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

  1. make:一般说GNU Make,是一个软件,用于将源代码文件编译为可执行的二进制文件,make工具主要用于完成自动化编译make工具编译的时候需要Makefile文件提供编译文件。
  2. Makefile:make工具所使用的文件,Makefile指明了编译规则。makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

4.2 利用make工具完成上一小节的自动化编译过程

4.2.1 编写makefile文件

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

4.2.2 利用make工具自动生成可执行程序

4.2.3 总结

      利用make工具完成自动化编译的大致步骤如下:

  1. 提供好所有的源文件.c和makefile文件
  2. 执行命令make, 自动生成编译链接四个阶段的所有文件 
  3. 清理中间的目标文件,执行命令: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)退出调试
  1. l +行号 就能跳转到该行。
  2. l +文件名:行号 能跳转文件 跳转别的文件的第几行 l add.c :1;
  3. 显示函数调用的栈关系 上边信息显示当前所在位置,下面信息显示执行完当前程序会回到哪一行。  

5.3 使用GDB软件调试程序的基本步骤

       GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等 IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。调试程序的基本步骤如下:

  1. 生成包含调试信息的Debug版本,如:gcc  -o test test.c -g
  2. 执行命令:gdb  test
  3. 进入调试,利用常用的命令

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”表示执行的行数(这里姑且先认为是执行的真实行数)。但有些场景下…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

ES6从入门到精通:前言

ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

【AI学习】三、AI算法中的向量

在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...