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”在单步执行的时候,只有当前线程会执行;

      以上就是全部内容!请务必掌握,这是后续学习的基础,欢迎大家点赞加关注评论,您的支持是我前进最大的动力!下期再见! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】常见命令:fping的介绍和用法举例

一、fping命令的安装 在终端中输入如下命令(Ubuntu系统使用apt install,CentOS系统使用yum install) sudo apt install fping安装效果(截图): 二、fping命令的用法和选项 fping命令用于检测主机是否存在…

2024最新 Jenkins + Docker实战教程(一) - Jenkins介绍及安装

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

DiffMap:首个利用LDM来增强高精地图构建的网络

论文标题: DiffMap: Enhancing Map Segmentation with Map Prior Using Diffusion Model 论文作者: Peijin Jia, Tuopu Wen, Ziang Luo, Mengmeng Yang, Kun Jiang, Zhiquan Lei, Xuewei Tang, Ziyuan Liu, Le Cui, Kehua Sheng, Bo Zhang, Diange Ya…

大数据工具之HIVE-参数调优,调度乱码(二)

一、调度乱码 在利用HUE工具,搭建WORKFLOW流程的过程中,如果直接执行hivesql数据正常,不会出现乱码现象,如果利用WORKFLOW搭建的流程,进行数据的拉取,会出现数据中文乱码现象,这些乱码主要是由于select 中的硬编码中文导致出现的现象 具体现象如下: select case when …

auto关键字(C++11)

auto关键字(C11) 文章目录 auto关键字(C11)前言一、auto使用规则二、auto不适用的场景三、auto推荐适用的场景总结 前言 在C11中,auto关键字能够自动推导出变量的实际类型,可以帮助我们写出更加简洁、现代…

java8新特性——函数式编程详解

目录 一 概述1.1 背景1.2 函数式编程的意义1.3 函数式编程的发展 Lambda表达式1.1 介绍1.2 使用Lambda的好处1.3 Lambda方法1.3.1 Lambda表达式结构1.3.2 Lambda表达式的特征 1.4 Lambda的使用1.4.1 定义函数式接口1.4.2 Lambda表达式实现函数式接口1.4.3 简化Lambda表达式1.4.…

k8s devops实战教程+生产实践+可就业

k8s devops实战教程 简介教程涉及到内容教程获取学习教程后的收货助学群 简介 越来越多的企业应用云原生化,催生很多应用的部署方式也发生了很多变化。 从物理机部署应用过度到虚机部署应用再到应用容器化,从单应用再到服务拆分为微服务,靠人…

【手把手搓组件库】从零开始实现Element Plus--组件开发

从零开始实现Element Plus--组件开发 nvmnvm的作用:nvm的使用方法 需求分析提示词Kimi 生成产品需求文档kimi 生成测试用例 初始化 vitest完善 Button 组件1、定义 types.ts2、Button.vue 引入 types.ts3、添加Button样式点击事件 添加节流添加 Icon 集成 StoryBook…

红黑树封装map和set

红黑树源代码 我们将由下列的KV模型红黑树来模拟封装STL库中的map和set 注意&#xff1a;为了实现封装map和set&#xff0c;我们需要对下列源码进行优化。 #pragma once #include<iostream> using namespace std; //枚举类型的颜色分类 enum Colour {RED,BLACK };//定…

Collection

Collection是单列集合的祖宗接口&#xff0c;它的功能是全部单列集合都可以继承使用。 1.添加元素 public class test {public static void main(String [] args) {Collection<String> colnew ArrayList<>();col.add("aaa");col.add("bbb");…

多签名钱包

相交于硬件钱包的物理上丢失和密钥遗忘&#xff0c;多签名钱包在保证安全不易被破解的基础上&#xff0c;解决了部分密钥丢失的问题。 相比于BTC之前讲到的脚本钱包&#xff08;BTC—脚本&#xff09;&#xff0c;ETH的多签钱包设计可以通过智能合约来实现 设计思路 工作原理…

辐射度技术在AI去衣中的魅力与科学

引言&#xff1a; 在当今的数字化时代&#xff0c;人工智能正逐渐渗透到我们生活的方方面面。其中&#xff0c;AI去衣技术作为一项颇具争议但又不失其科技创新的应用&#xff0c;正引起越来越多的关注和讨论。而在实现高质量图像渲染的过程中&#xff0c;辐射度技术凭借其卓越的…

移动端开发 笔记01

目录 01 移动端的概述 02 移动端的视口标签 03 开发中的二倍图 04 流式布局 05 弹性盒子布局 01 移动端的概述 移动端包括:手机 平板 便携式设备 目前主流的移动端开发: 安卓设备 IOS设备 只要移动端支持浏览器 那么就可以使用浏览器开发移动端项目 开发移动端 使用…

GNSS中的多路径效应原理及计算方法

1 多路径效应原理 图1 多路径效应原理图 2 计算方法 如需原文&#xff0c;可加多源融合定位与智能控制讨论群获取,QQ群号&#xff1a;51885949

6、phpjm混淆解密和php反序列化

题目&#xff1a;青少年雏形系统 1、打开链接也是一个登入面板 2、尝试了sqlmap没头绪 3、尝试御剑&#xff0c;发现一个www.zip 4、下载打开&#xff0c;有一个php文件打开有一段phpjm混淆加密 5、使用手工解混淆 具体解法链接&#xff1a;奇安信攻防社区-phpjm混淆解密浅谈…

页面<html>上多了一个滚动条,定位发现是<body>里面多了一个id为trans-tooltip的div

现象分析&#xff1a; 页面根标签html多了一个滚动条&#xff0c;发现body里面多了一个id为trans-tooltip的div&#xff0c;虽然width为0&#xff0c;height为0&#xff0c;但是其子元素还是有高度&#xff0c;占据了空间&#xff0c;最终导致了滚动条&#xff1b; 根本原因&…

SpringBoot注解--09--idea创建spring boot项目,java版本只能选择17和21

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 idea创建spring boot项目1.问题描述2.原因3.解决方法方案一&#xff1a;升级JDK版本至17或更高方案二&#xff1a;替换Spring初始化的源https://start.aliyun.com i…

可以在搜索结果中屏蔽指定网站的插件

可以在搜索结果中屏蔽指定网站的插件 | LogDict背景 在搜索引擎中搜索问题, 往往充斥各种无效内容 比如搜个技术类的问题, 前几页CSDN, 百度百家号, 百度经验, 百度知道, 腾讯云各类云爬的水文 CSDN基本都是复制粘贴的, 甚至格式都乱码了, 虽然我以前也干过 要复制粘贴无所谓, …

最小二乘法-超详细推导(转换为矩阵乘法推导,矩阵求导推导)

最小二乘法就是让均方误差最小。 下面是损失函数转换为矩阵方式的详解 如何让其最小&#xff0c;在导数为0的地方取极小值。 问&#xff1a;导数为0的地方可能去极大值&#xff0c;也可能是极小值&#xff0c;凭什么说导数为0就是极小值&#xff1f; 答&#xff1a;因为使用…