首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

从创建进程到进入main函数,发生了什么?

操作系统内核将负责进程的创建,主要有下面几个工作要做: 创建内核中用于描述进程的数据结构,在Linux上是task_struct 创建新进程的页目录、页表,用于构建新进程的内存地址空间 在Linux内核中...我们使用C、C++等高级语言编写的代码,最终通过编译器会编译生成可执行文件,在Linux上,是ELF格式,在Windows上,称之为PE文件。...前面提到,子进程是通过sys_execve系统调用进入到内核中的,在后面完成可执行文件的分析后,拿到了ELF文件的入口地址,将会去修改原来保存在堆栈上的上下文信息,将EIP指向ELF文件的入口地址。...在_start的结尾,调用了 __libc_start_main 函数,而这个函数,位于libc.so中。 你可能疑惑,这个函数是哪里冒出来的,我们的代码中并没有用到它呢?...在通过GCC进行编译时,编译器将自动完成运行时库的链接,将我们的main函数封装起来,由它来调用。

1.4K30

Linux编译器---gccg++使用详解

它将C源代码编译成目标代码,并调用GCC的后端来生成可执行文件或库文件。 特点:gcc支持多种C语言标准,如ANSI C(C89/C90)、C99和C11。...g++: 功能:g++是GCC套件中用于编译C++代码的编译器。它是gcc的C++编译器前端,通过调用GCC的后端来生成目标代码。...特点:g++支持多种C++标准,如C++98、C++11、C++14、C++17等。开发人员可以使用g++来编译符合不同C++标准的代码,并生成高效的可执行文件或库文件。...⭐gcc/g++的编译指令(以gcc为例) 首先可以查看一下自己的Linux上gcc的版本,确认是否有gcc编译器。...函数库通常以文件或模块的形式存在,可以在程序中引用和调用其中的函数来完成相应的操作。

85620
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    深入浅出GCC编译器

    as 汇编器用于把汇编文件(汇编语言)转换为目标问价(机器码),完成 .s到 .o 的工作; ld 链接器用于把编译生成的多个目标文件链接组织为可执行文件; 这两个工具我们一般不会直接调用,它们大多是在...语义分析:语义分析是编译过程的一个逻辑阶段,语义是解释控制信息每个部分的意义,它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应,此阶段的任务是对结构上正确的源程序进行上下文有关性质的审查,....ii C++源文件预处理后生成的文件 .S 预编译后的汇编源文件 补充一下C++的源文件后缀名,通过man可以查到 可以看到,我们上面并没有列出可执行文件的后缀,原因是,在Linux中,可执行文件并没有特定的后缀...这里再次强调,在Linux中,可执行文件并没有特定的后缀,Linux主要通过文件的权限来判断文件是否可执行,只要权限是可行的,那么这个文件就是可执行的,和他什么后缀,什么名称没有关系。...实际上,main函数没有return语句至少应该提示警告信息的,甚至在VS中,这个文件直接就无法通过编译且直接报错的。

    53210

    含大量图文解析及例程 | Linux下的ELF文件、链接、加载与库(下)

    事实上操作系统装载程序之后首先运行的代码并不是我们编写的main函数的第一行,而是某些运行库的代码,它们负责初始化main函数正常执行所需要的环境,并负责调用main函数,并且在main返回之后,记录main...,简单来说:可执行文件中有main函数,动态库中没有main函数,可执行文件可以被程序执行,动态库需要依赖程序调用者。...在可执行文件的所有符号中,main函数是一个很特别的函数,对C/C++程序开发人员来说,main函数是整个程序的起点;但是,main函数却不是程序启动后真正首先执行的代码。...比如,程序的启动代码,放在内存映射的起始处,在执行main函数之前执行以及在程序终止后完成一些任务编译动态库时,链接器没有添加这部分代码。这是可执行文件和动态库之间的区别。...我们之前已经介绍过,在动态链接的可执行文件中,外部符号的地址在程序加载、运行的过程中才被确定下来。这个链接加载器 ld 就是负责完成这个工作的。

    1.5K23

    浅析C++内存布局

    C++程序在内存中的布局是怎样的?总结下C++内存布局的相关知识。 概述 简单总结下C++变量在内存中的布局和可执行文件相关的知识。暂未涉及虚函数,虚函数表,类的继承和多态等C++对象的内存模型。...常见的文件如在Linux上的可执行文件,动态库(*.so)或者静态库(*.a) 等包含ELF格式的文件。 什么是ELF文件?...在window平台上,可执行程序为xxx.exe。它产生两种东西:指令和数据。.exe程序存放在磁盘中,执行时被加载到内存中,不是物理内存,而是虚拟内存空间,.text中存放指令。  ...包括:代码指令是如何保存的,库文件如何与应用程序代码静态链接,应用程序如何被装载到内存中并开始运行,动态链接如何实现,C/C++运行库的工作原理,以及操作系统提供的系统服务是如何被调用的。...linux系统从开机到启动,执行流程从代码层面看大致经历: 设备上电后执行一段bootloader的汇编阶段。

    1.2K40

    没想到进入main函数前,发生了这么多事!

    exe(windows上)或者elf(linux上)。...咱们就从这个可执行文件入手,以Linux系统上的Java8版本为例,用反汇编神器IDA打开可以看到,这个可执行文件的入口: image.png 和咱们在上一篇分析的流程符合,进入这个程序启动入口后,...如果定义了JAVAW,则是一个Win32 GUI的程序,当然在Linux上是肯定没有这个宏定义的,不过这不是本文的主题。 可以看到main函数只是一个包装,直接就进入了JLI_Launch中。...这个函数位于同目录下的隔壁java.c文件中,是JVM非常重要的初始化函数,主要完成了下面几件事情: 参数解析,环境配置 检查Java运行环境 加载JVM核心动态库libjvm.so 创建并初始化Java...在JLI_Launch的结尾,调用了ContinueInNewThread,从这个函数的名字我们也能窥探它的作用。

    84230

    SLAM——Linux操作学习

    make 把一些中间生成文件全部放在了build下面,比较好管理,给别人发送c++的源代码的时候也比较方便 3、连接到库 在c++中,并不是所有的代码都会编译成可执行文件,只有带main函数的才会生成可执行文件...但是它没有main函数,这意味着这个库中没有可执行文件。...make 这是,在build文件夹就会生成libhello.a文件,这就是我们得到的库。在Linux中,库分为静态库和共享库。静态库以.a为后缀名,共享库以.so结尾。...int main(int argc, char** argv) { printHello(); return 0; } 然后在CMakeLists.txt中添加一个可执行程序的生成命令,链接到刚才使用的库上...3、如果可执行文件箱套调用库文件中的函数,他需要参考这个库提供的头文件,以明白调用的格式,同 时,要把可执行程序链接到库文件上。

    80220

    Hello World背后的故事:如何在Linux上编译C语言程序

    无论是在Windows上还是Linux上,.c、.cpp文件是无法直接运行的,需要使用编译工具将.c等源代码文件转化为可执行文件。例如,.exe文件可以在Windows上被计算机运行。...GCC最初名为GNU C Compiler,当时它只是一款C语言的编译器,不过随着后续迭代,它支持C++、Fortran、Go等语言,GCC也因此成为一个编译器集合。..._64架构中,printf()方法在底层是用call puts来实现的,call用来调用一个函数。...在Linux中,一个新的程序都是由父进程调用fork(),生成一个子进程,然后再调用execve(),将可执行文件加载进来,才能被操作系统执行。...main函数,callq调用了某个方法,这个方法在内存中的地址还是不确定的。

    1.9K11

    【技术】Linux中编译C++代码的g++工具,以及g++的常用操作指令

    这是一篇技术文章,如果你想继续阅读,并希望从中有所收获,你现在应当具备以下技能: C++ 编程语言基础 Linux 操作系统基础 本文目录 1....GCC 编译器支持编译 Go、Object-C、Object-C ++、Fortran、Ada、BRIG(HSAIL)等程序; Linux 开发 C/C++ 一定要熟悉 GCC; VSCode 是通过调用...# 编译test.cpp 文件,在 Linux 下,默认产生名为 a.out 的二进制可执行文件 g++ test.cpp 实际上,上面的一步编译指令包含了以下几个过程 第一步:预处理 Pre-processing...二进制文件 # -o 编译选项来为将产生的可执行文件指定文件名,如果不使用-o参数,在Linux下默认输出名为 a.out 的可执行文件 g++ test.o -o test 3. g++重要编译参数.../local/lib里的库直接调用 -l 参数就能链接,这三个库目录我们在下文中叫做系统库目录 # 链接 glog库 编译 g++ -lglog test.cpp 如果库文件没有放在系统库目录中,需要使用

    4.9K20

    C++ 编译体系入门指北

    生成的目标文件通常以.o(在Unix-like系统中)或.obj(在Windows系统中)为后缀。 链接(Linking):链接器将一个或多个目标文件以及需要的库链接成一个可执行文件或库。...构建系统 随着项目工程越来越复杂,源代码文件越来越多,编译配置项根据场景的不同越来越复杂(例如,Debug模式和Release模式下编译参数不一样)的时候,依然通过直接调用这些命令的时候就会很复杂,我们需要编写大量复杂的命令行才能完成一个复杂项目的编译工作...基于这样的背景,我们诞生了构建系统(Build System)。 在Linux/Unix上的构建系统历史最悠久的就是make工具,而与之配合的就是Makefile配置文件。...图片引自:https://www.cnblogs.com/w4ngzhen/p/17695080.html 构建系统在底层依赖使用的是编译工具链,只是进行了一定的用户友好的抽象,并降低了项目编译的复杂度...vcpkg vcpkg 是由微软开发的 C++ 包管理器,专注于简化库的获取和集成。它特别适合 Windows 平台,但也支持 Linux 和 macOS。

    56921

    C++系列-附录-windows下安装C++环境

    Clang在许多平台上可用,并被广泛应用于开发工具和IDE中。 Visual C++:Visual C++ 是微软公司开发的C++编译器。...Visual C++: cl /EHsc my_program.cpp 这个命令使用 cl 命令来调用 Visual C++ 编译器,编译名为 my_program.cpp 的源文件,并生成可执行文件。...MinGW MinGW(Minimalist GNU for Windows)是一套在Windows上使用GCC工具链的开发工具集合。它提供了一系列命令来编译和构建C++程序。...它提供了 GCC 编译器套件的 Windows 版本,并通过命令行界面(CLI)提供与 GCC 类似的命令和选项。...下载C++环境 下载安装编译器Mingw-w64 参考网页:https://www.msys2.org/ 在网页中点击下载链接 按步骤安装完成,本文路径使用D:\Mingw\W64 打开MSYS的终端并输入

    28710

    【Linux】深度解析与实战应用:GCCG++编译器入门指南

    1. gcc/g++简介   在Linux系统中,GCC(GNU Compiler Collection)是极其重要且广泛使用的编译器,它支持多种编程语言,包括C、C++、Objective-C、Java...在Linux系统中,gcc和g++是GCC套件中用于编译C和C++程序的工具。gcc专门用于C语言程序的编译,而g++则专注于C++程序的编译。...动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。 4....调试   在Linux操作系统的软件开发中,调试是一个至关重要的环节。它帮助开发者定位和解决程序中的错误、优化代码性能以及深入理解程序的运行过程。...总结   GCC是Linux下极其重要的编译器,通过gcc和g++,开发者可以方便地将C和C++源代码编译成可执行文件。了解GCC的编译过程和常用选项,对于Linux下的软件开发至关重要。

    21810

    CSAPP---第七章-链接

    此时,任何不包含在E中的成员目标文件都简单被丢弃,而链接器继续处理下一个输入文件。 如果当链接器完成对命令行上输入文件的扫描后,U是非空的,那么链接器就会输出一个错误并终止。...---- 加载可执行文件 要运行可执行目标文件 prog,我们可以在 Linux shell 的命令行中输入它的名字: linux> ....,叫做 Java 本地接口(Java Native Interface,JNI),它允许 Java 程序调用“本地的” C 和 C++ 函数。...那在编译阶段就已生成好的call指令,怎么感知这个已重定位好的数据段内容呢? 答案是:链接器生成一段额外的小代码片段,通过这段代码支获取printf函数地址,并完成对它的调用。...在加载时,加载器将部分链接的可执行文件映射到内存,然后调用动态链接器,它通过加载共享库和重定位程序中的引用来完成链接任务。

    92110

    Linux工具学习之【gccg++】

    ---- 前言 书接上文,我们已经学习了 Linux 中的编辑器 vim 的相关使用方法,现在已经能直接在 Linux 中编写C/C++代码,有了代码之后就要尝试去编译并运行它,此时就可以学习一下 Linux...a.out ,当然前提是代码没问题,所以这样看来编译一个文件还是很简单的 $ gcc 源文件 //直接编译源文件,生成默认可执行文件为 a.out 可能有的人不想让它生成默认的 a.out ,想生成为指定文件...,就是在调用标准库中的函数,而这些标准库都在 /usr/include 这个目录中,这个文件就是 Linux 中的C语言动态库;除了 动态库 外还有 静态库 动态库 动态库 即通过 动态链接 的库,动态库...又称 共享库,因为 动态库 中的内容是被所有程序共享的,简言之 动态库 中的代码只需要存在一份,程序需要使用时,直接通过对应位置调用就行了 Linux 中默认使用 动态链接 的方式,我们可以通过指令...,比较占空间 因为这种方式很占空间,所以 Linux 中默认使用 动态链接 的方式 类比记忆 静态库 就像是把网吧里的电脑,买了一台同款的在自己寝室(调用某个函数),一台还好,如果买了很多台,寝室自然就没有空间了

    21620

    【linux学习指南】Linux编译器 gcc和g++使用

    linux-vdso.so.1: 这是一个虚拟动态共享对象(VDSO),用于提供一些内核功能的用户空间接口。它通常用于提高系统调用的效率。...它的路径是 /lib64/libc.so.6,并且它在内存中的加载地址是 0x00007f11a5172000。.../lib64/ld-linux-x86-64.so.2: 这是动态链接器(或加载器),负责在程序运行时加载所需的共享库并进行链接。它的加载地址是 0x00007f11a5540000。...动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时 链接文件加载库,这样可以节省系统的开销。...动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态 库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。

    20810

    Android程序中,内嵌ELF可执行文件--Android开发C语言混合编程总结

    Java是一种跨CPU的语言,并不要求指定特定的CPU。而C/C++语言,在不同的CPU上,都需要进行特定的编译。...APK包安装的时候,根据确定的硬件平台,实际只有一个对应的.so文件会被安装的设备上。 调用一个完整的命令行可执行文件 调用完整的可执行文件,这在Android中并不是官方推荐的。...不同的操作系统,有不同的可执行文件格式。比如Windows的EXE/PE格式,macOS的Mach-O。在Linux上,就是ELF格式。...所以编译出的二进制代码,需要作为数据文件,放入APK的资源区。 在Java代码中,根据检测到的CPU类型,把对应的可执行文件,从数据区拷贝到Android设备上,并设置为可执行。...在Java代码中调用可执行程序,并获取结果。 编译可执行文件 首先当然是准备一个C/C++代码,比如我们用一个最经典的Hello World。

    1.9K40

    Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结

    Java是一种跨CPU的语言,并不要求指定特定的CPU。而C/C++语言,在不同的CPU上,都需要进行特定的编译。...APK包安装的时候,根据确定的硬件平台,实际只有一个对应的.so文件会被安装的设备上。 调用一个完整的命令行可执行文件 调用完整的可执行文件,这在Android中并不是官方推荐的。...但通常基于Linux系统的编程,这又是不可避免的。很多必要操作,如果开发系统的SDK支持不足,或者用起来不方便。都可以通过直接访问系统层参数文件或者系统层可执行文件来完成。...不同的操作系统,有不同的可执行文件格式。比如Windows的EXE/PE格式,macOS的Mach-O。在Linux上,就是ELF格式。...在Java代码中,根据检测到的CPU类型,把对应的可执行文件,从数据区拷贝到Android设备上,并设置为可执行。 在Java代码中调用可执行程序,并获取结果。

    1.8K40

    动态链接的步骤与实现

    动态链接器的自举 我们知道动态链接器本身也是一个共享对象,但是事实上它有一些特殊性。对于普通共享对象文件来说,它的重定位工作由动态链接器来完成。...从这一步开始,动态链接器代码中才可以使用自己的全局变量和静态变量。 实际上在动态链接器的自举代码中,除了不可以使用全局变量和静态变量之外,甚至不能调用函数,即动态链接器本身的函数也不能调用。...Linux动态链接器是个很有意思的东西,它本身是一个共享对象,它的路径是lib/ld-linux.so.2,这实际上是个软链接,它指向lib/ld-x.y.z.so,这个才是真正的动态连接器文件。...自举的过程需要十分的小心谨慎,因为有很多限制.这个我们在前面已经介绍过了。完成自举之后就可以调用其他函数并访问全局变量了。...实际上的ld- linux.so.2是PIC的。 动态链接器可以被当作可执行文件运行,那么的装载地址应该是多少?

    1.4K20

    编译原理基础

    许多操作系统,包括许多类Unix系统,如Linux及BSD家族都采用GCC作为标准编译器。 GCC原本用C开发,后来因为LLVM、Clang的崛起,它更快地将开发语言转换为C++。...许多C的爱好者在对C++一知半解的情况下主观认定C++的性能一定会输给C,但是Ian Lance Taylor给出了不同的意见,并表明C++不但性能不输给C,而且能设计出更好,更容易维护的程序。...简单来说,gcc 指的是 GCC 中的 GNU C Compiler(C 编译器);g++ 是 G++ 中的 GNU C++ Compiler(C++ 编译器),但实际上 gcc 和 g++ 都不是编译器...,也不是编译器的集合,它们只是一种驱动器,根据参数中的文件类型,调用对应的 GNU 编译器,所以更准确的说法是:gcc 调用了 C compiler, g++ 调用了C++ compiler。...GNU 工具链在针对嵌入式系统的 Linux内核、BSD 及其它软件的开发中起着至关重要的作用。

    89110
    领券