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.mzph.cn/web/15524.shtml

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

相关文章

一千题,No.0025(Chess For Three)

描述 Three friends gathered to play a few games of chess together. In every game, two of them play against each other. The winner gets 2 points while the loser gets 0, and in case of a draw, both players get 1 point each. Note that the same pair of playe…

【MySQL精通之路】SQL语句(3)-锁和事务语句

目录 1.START TRANSACTION、COMMIT和ROLLBACK语句 2.无法回滚的语句 3.导致隐含COMMIT的语句 4.SAVEPOINT、ROLLBACK TO SAVEPOINT和RELEASE SAVEPOINT语句 5.LOCK INSTANCE FOR BACKUP和UNLOCK INSTANCE语句 6.LOCK TABLE和UNLOCK TABLES语句 6.1 表锁获取 6.2 表锁释放…

qemu+gdb调试linux内核

打开CONFIG_DEBUG_INFO,编译内核 通过图形菜单配置该宏,执行make menuconfig。 kernel hacking —> compile-time checks and compiler options —> compile the kernel with debug info 验证是否打开成功,grep -nr “CONFIG_DEBUG_INFO” .config。 打开成功,然后…

plsql 学习

过程化编程语言 赋值:: ||:连接符号 dbms_output.put_line() :输出的语句 var_name ACCOUNTLIBRARY.USERNAME%type; 变量名;某个表的数据类型;赋值给变量名 用下面的方法更好用 异常exception 循…

力扣HOT100 - 75. 颜色分类

解题思路&#xff1a; 单指针&#xff0c;对数组进行两次遍历。 class Solution {public void sortColors(int[] nums) {int p 0;int n nums.length;for (int i 0; i < n; i) {if (nums[i] 0) {int tmp nums[i];nums[i] nums[p];nums[p] tmp;p;}}for (int i p; i …

java库和包的概念

在Java中&#xff0c;"库"和"包"是两个不同的概念&#xff0c;但它们之间存在着密切的关联。 库&#xff08;Library&#xff09; 定义&#xff1a;库是一组已经编写好的代码和资源&#xff0c;用于解决特定的问题或提供特定的功能。它可以包含一个或多个…

【前端每日基础】day19——回调函数

回调函数 回调函数是一种常见的编程概念&#xff0c;它是指在函数执行完毕后&#xff0c;将另一个函数作为参数传递给它&#xff0c;以便在特定条件满足时调用这个函数。回调函数通常用于处理异步操作、事件处理、定时器等场景&#xff0c;以实现非阻塞式的程序设计。 特点和…

存储+调优:存储-IP-SAN-EXTENSION

存储调优&#xff1a;存储-IP-SAN-EXTENSION 文件系统的锁标记 GFS&#xff08;锁表空间&#xff09; ----------- ------------ ------------- 节点 | ndoe1 | | node2 | | node3 | ---------- ------…

断更是我的错

打算在暑假每天两个文章&#xff0c;大概是6月20多号开始吧。

vue3中watch语法

在Vue 3中&#xff0c;watch仍然是一个用于观察和响应Vue实例上的数据变化的选项。watch选项接受一个对象&#xff0c;该对象中的属性对应要观察的数据属性&#xff0c;并指定对应的回调函数&#xff0c;用于处理数据变化时的逻辑。 watch选项的语法如下&#xff1a; watch: …

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

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

ORACLE 6节点组成的ACFS文件系统异常的分析思路

近期遇到多次6节点集群的ACFS文件系统环境异常问题&#xff1b;如24日中午12点附近出现ACFS文件系统访问异常&#xff0c;通过查看集群ALERT日志、CSSD进程日志及OSW监控软件的日志&#xff0c;可以发现OSW监控软件在11:55-12:40分时没有收集到虚拟机LINUX主机的监控数据&#…

【OceanBase诊断调优】—— 直连普通租户时遇到报错:Tenant not in this server

本文介绍了直连 OceanBase 数据库中的普通租户时&#xff0c;出现报错&#xff1a;ERROR 5150 (HY000) : Tenant not in this server 的处理方法。 问题描述 在 n-n 或者 n-n-n (n>1) 的部署架构中&#xff0c;使用 2881 端口 直连 OceanBase 集群的普通租户&#xff0c;可…

ChatGPT大语言模型发展历史

技术背景与OpenAI成立 2010年代初&#xff1a;随着深度学习技术的突破&#xff0c;特别是循环神经网络(RNN)和长短时记忆网络(LSTM)的成功应用&#xff0c;自然语言处理(NLP)领域开始经历一场革命。2015年12月&#xff1a;OpenAI作为一个旨在确保人工智能(AI)研究造福全人类的…

Java并行流

Java并行流 什么是并行流&#xff1f;并行流的优缺点优点缺点 如何使用&#xff1f;1.创建流2.转换为并行流3.流操作4.收集结果5.关闭流 并行流的本质1.任务划分和调度2.并发处理数据3.任务结果合并4.性能优化 参考文献官方文档 什么是并行流&#xff1f; 并行流&#xff08;p…

【C++风云录】揭秘医疗机器人:技术解析与应用探索

打造智能医疗&#xff1a;医疗机器人技术与手术辅助 前言 本文将在深度和广度上探讨六种尖端医疗机器人系统&#xff0c;并重点介绍其应用、C控制接口及其功能。这些机器人系统分别是ROSA Robot、Da Vinci Surgical SystemSDK、Intuitive Surgical’s da Vinci Xi、Medroboti…

黑龙江等保测评新要求下的政府信息化安全实践案例分析

在数字化转型的浪潮中&#xff0c;政府机构作为社会管理和公共服务的核心&#xff0c;其信息安全的重要性日益凸显。近期&#xff0c;黑龙江省积极响应国家网络安全战略&#xff0c;依据最新的等级保护测评&#xff08;简称“等保测评”&#xff09;要求&#xff0c;对政府信息…

SpringBoot运维篇(打包,多环境,日志)

文章目录 一、SpringBoot程序的打包与运行二、配置高级三、多环境开发四、日志 一、SpringBoot程序的打包与运行 刚开始做开发学习的小伙伴可能在有一个知识上面有错误的认知&#xff0c;我们天天写程序是在Idea下写的&#xff0c;运行也是在Idea下运行的。 ​但是实际开发完成…

CDH6.3.2集成Flink1.17

直接运行脚本即可&#xff0c;一键输出相关依赖包 运行步骤已给到文档 下载地址

Html基础笔记

Html超文本标记语言 (HyperText Markup Language) 超文本 指的是网页中可以显示的内容(图片,超链接,视频,) 标记语言 标记–>标签(标注) 例如:买东西的时候—>商品具有标签,看到标签就知道商品的属性(价格,材质,型号等,) 标记语言就是提供了很多的标签,不同的标签…