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,一经查实,立即删除!

相关文章

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 …

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

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

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

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

【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;可…

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

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

CDH6.3.2集成Flink1.17

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

Html基础笔记

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

若依框架对于后端返回异常后怎么处理?

1、后端返回自定义异常serviceException 2、触发该异常后返回json数据 因为若依对请求和响应都封装了&#xff0c;所以根据返回值response获取不到Code值但若依提供了一个catch方法用来捕获返回异常的数据 3、处理的方法

antd design 自定义表头

<template><a-card :bordered"false"><div class"contentWrap"><!-- 查询区域 --><div class"table-page-search-wrapper"><a-form layout"inline" keyup.enter.native"searchQuery">&…

云端智享——记移动云手写docker-demo

目录 前言什么是移动云&#xff1f;为何我会使用移动云&#xff1f;移动云“好”在哪里&#xff1f;资源大屏显示继续项目部署其他细节 移动云产品的评价未来展望 前言 在如今这个万物都上云的时代&#xff0c;我们需要选择合适的云产品&#xff0c;而移动云有着独特的优势和广…

1.存储部分

1.Flash Memory--闪速存储器&#xff08;注&#xff1a;U盘&#xff0c;SD卡就是闪存&#xff09;在EEPROM基础上发展而来的&#xff0c;断电后也能保存信息&#xff0c;且可进行多次 快速擦除重写。注意&#xff1a;由于闪存需要先擦除再写入&#xff0c;因此闪存写的速度要比…

python-绘制五星红旗(非标准)

完整代码如下&#xff1a; #五星红旗&#xff08;非标准版&#xff09; from turtle import* import math from random import* tracer(0) penup() goto(-640,220) pendown() color(gold,gold) begin_fill() for i in range(5): fd(150) right(144) # 大五角星 penup(…

【一个糟糕的词:省流】

今日思考&#xff0c;博主分享&#x1f4dd;&#xff0c;原文如下&#xff0c; 我最近听到了一个特别糟糕的词叫省流。我甚至认为这个词可以用来衡量一个人的智商啊&#xff0c;我们可以把一个知识简单的分成三部分问题&#xff0c;答案思维方式就是这个答案是怎么推导出来的啊…

Python数据可视化(二)

Patches绘制几何图形 模块 patches 主要用来完成多边形的绘制工作。这些多边形都是以类&#xff08;Class&#xff09;的形式出现的&#xff0c; 主要包括圆&#xff08;Circle&#xff09;、椭圆&#xff08;Ellipse&#xff09;、矩形&#xff08;Rectangle&#xff09;、圆…

【全开源】知识库文档系统源码(ThinkPHP+FastAdmin)

知识库文档系统源码&#xff1a;构建智慧知识库的基石 引言 在当今信息爆炸的时代&#xff0c;知识的有效管理和利用对于企业和个人来说至关重要。知识库文档系统源码正是为了满足这一需求而诞生的&#xff0c;它提供了一个高效、便捷的平台&#xff0c;帮助用户构建、管理、…

设计模式之创建型模式---原型模式(ProtoType)

文章目录 概述类图原型模式优缺点优点缺点 代码实现 概述 在有些系统中&#xff0c;往往会存在大量相同或者是相似的对象&#xff0c;比如一个围棋或者象棋程序中的旗子&#xff0c;这些旗子外形都差不多&#xff0c;只是演示或者是上面刻的内容不一样&#xff0c;若此时使用传…

Oblivion Desktop:一款强大的网络工具介绍

一款优秀的开源网络工具。 文章目录 Oblivion Desktop: 安全与隐私的网络工具软件背景开发背景 使用方法安装日常使用高级功能 总结 Oblivion Desktop: 安全与隐私的网络工具 软件背景 Oblivion Desktop 是一个由 BePass 团队开发的开源桌面应用&#xff0c;旨在为用户提供更…

【Qt】Qt组件设置背景图片

1. 方法1&#xff08;paintEvent方式&#xff09; 使用paintEvent()实现 1. .h文件中添加虚函数 protected:void paintEvent(QPaintEvent *event) override;添加虚函数方法&#xff1a; 选中父类&#xff0c;点击鼠标右键点击重构点击 Insert Virtual Funtion of Base Class…