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

linux下一个应用是如何被执行的

Linux系统下,一个应用从启动到执行main函数经历了什么:

  1. 加载器(loader):用户在终端启动一个程序时候,shell调用execve,执行程序的启动。
  2. 内核态操作:execve做了以下几个事情,(1)找到执行文件(2)读取ELF的文件头,各个段的头信息等,就知道程序的入口地址。
  3. 创建进程环境:(1)内核位进程分配新的资源,如进程控制块(PCB),内存空间等 (2)加载程序段:根据ELF文件的程序头,段头,内核将可执行文件的各个段加载到新的地址空间。(3)设置堆栈:为进程分配用户栈,并将命令行参数和环境变量拷贝到空户栈上,(4)动态连接器:如果程序是动态链接的,内核会加载elf文件中的动态链接器地址,并将控制权给它。
  4. 动态链接器:(1)解析符号:解析并加载所需要的共享库,满足所有未定义的符号。(2)重定位:修改程序中的地址引用,使其找到正确的内存地址。(3)初始化构造函数:执行共享库中的初始化代码(.init中的代码),通常是调用构造函数
  5. 用户态准备:在动态链接器完成工作后,程序的控制权会传递给程序的入口点(—_start)
  6. CRT(C运行时)初始化:程序的入口点_start通常时由c运行时库提供的启动代码。它完成一下操作: (1)堆栈和全局数据的初始化:设置堆栈指针,初始化全局变量和静态变量。(2)调用程序初始化函数:执行编译器生成的初始化函数(.init_array数组中的函数)。 (3)准备参数:将命令行参数和环境变量传递给main函数。
  7. 调用main

主要有两个比较重要的部分:

1.进程的创建

当一个进程通过for系统调用创建的时候,实际上他是当前进程的一个副本以及大部分资源的复制。当时进程的堆栈不是完全复制的,而是继承了父进程堆栈状态,但会为新进程创建一个新的堆栈顶部, 这是因为fork之后通常紧接着“exec”函数来替换进程执行的上下文,此时进程会加载一个新的程序。

进程创建时候的资源分配

在fork时,新进程继承了以下资源:

打开的文件描述符,环境变量,信号处理程序,进程ID,父进程ID,进程组ID,会话ID, 当前的工作目录,根目录,文件权限掩码,资源限制,终端控制,内存映射。

2.后续的堆栈设置

当fork之后使用exec来执行一个新的程序时候会发生以下状况:

-新程序的二进制文件将被加载到内存中覆盖原来的进程文本段,数据段和bss段

-系统调用会设置新城西的入口地址(_start),并准备好堆栈

-传给exec的参数和环境变量放在堆栈上,便以新的城西访问他们

-新程序的堆栈将被初始化,通常是一个比较高的虚拟地址,向下增长


http://www.kler.cn/a/374768.html

相关文章:

  • 后台管理系统的通用权限解决方案(九)SpringBoot整合jjwt实现登录认证鉴权
  • o1驾驶无人机后空翻,OpenAI开发者日惊掉下巴!2分钟爆改代码写App
  • 【C++】string 类模拟实现:深入探索字符串操作原理
  • 瓦片与数据使用要素服务的区别
  • 基于Unet卷积神经网络的脑肿瘤MRI分割
  • KOA——基于Node的Web框架
  • 便携剃须刀性能王者,小但专业,未野MAX SE剃须刀测评
  • Arduino 74HC595芯片引脚拓展使用详解
  • 使用 python中 pandas 将 Excel 转换为 CSV 文件
  • 无人机3D模拟训练飞行技术详解
  • springboot导出pdf,解决中文问题
  • 在 Android 设备上部署一个 LLM(大语言模型)并通过 Binder 通信提供服务
  • Java 字符流详解
  • Zoho Desk系统解锁工单自动化 分配效率翻倍
  • ffmpeg拉流分段存储到文件-笔记
  • SC5120家庭总线收发器可pin to pin兼容MAX22088
  • WAF+AI结合,雷池社区版的强大防守能力
  • scp免密传输教程
  • QT 跨平台优势独特,效果实例设计精彩呈现
  • 【Redis】内存淘汰策略
  • sqoop Oracle to hive出现 Error Msg = ORA-00933: SQL 命令未正确结束
  • 3周岁孤独症儿童:治愈的希望还是幻想?
  • 一文读懂 HTTP Cookies
  • Python批量查找包含多个关键词的PDF文件
  • CSP/信奥赛C++刷题训练:经典差分例题(2):洛谷P9904 :Mieszanie kolorów
  • TS:如何推导函数类型