进程程序替换与exec系统调用

进程程序替换

进程程序替换是指将一个正在运行的进程替换为另一个可执行程序。它的本质是调用了Linux操作系统中的exec系统调用。而exec系统调用是一个家族函数,例如execlexecvexecleexecve等。它们的共同特点是当当前进程执行到该函数时,就会直接跳转到新的程序并开始执行新的可执行文件。

exec系统调用

所以我们要想知道怎样进行进程程序替换就要先会使用exec系统调用,而且exec系统调用的家族函数只要掌握了一个,其他的也就大差不差了。

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
  • 如果调用出错则返回-1
  • 所以exec函数只有出错的返回值而没有成功的返回值。

所以就先详细的讲一下execl函数。

execl系统调用函数

#include <unistd.h>int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);

该函数接受可执行文件的路径(path)以及一系列的参数(arg0argn),最后以一个空指针(char *)0结尾。arg0代表可执行文件本身(即argv[0]),arg1argn是命令行参数。

代码示例

int main()
{cout<<"before execl"<<endl;//执行前execl("/usr/bin/ls","ls","-l","-a",NULL);//必须以空结束cout<<"after execl"<<endl;//执行后return 0;
}

 我们不难发现我们自己写的一个可执行程序运行的时候,在调用execl函数时会执行新的命令(可执行程序文件)而且在执行完成之后就直接结束了,并没有执行我们自己写的可执行程序的后续操作。就相当于在代码中调用其他程序。所以可以初步得出:execl函数成功执行时,当前进程将被替换为指定的可执行文件,并从该文件开始执行。注意,execl函数不会创建新的进程,而是将当前进程替换为新的可执行文件。

函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。

如果调用出错则返回-1
所以exec函数只有出错的返回值而没有成功的返回值。

执行原理

当我们运行我们的可执行程序时,该程序就已经变成了进程了,所以自然就少不了进程PCB以及进程地址空间和页表,和代码数据所映射的物理内存。但是当我们执行到execl函数时,就要开始执行一个已有的全新程序(并不创建进程),而该已有的程序(文件)自然存在磁盘当中,所以我们运行这个新的程序时就要将程序加载进内存。但是关键的是该新程序中的代码和数据并不是另存的,而是直接以覆盖式的存放在原进程的代码和数据所在物理内存中对应的位置,并继续从新程序的启动例程开始执行

以上就是单进程程序替换的过程

多进程的程序替换 

int main()
{pid_t i=fork();if(i==0)//子进程{    cout<<"before execl,"<<"mypid:"<<getpid()<<endl;execl("/usr/bin/ls","ls","-l","-a",NULL);//必须以空 结束cout<<"after execl,"<<"mypid:"<<getpid()<<endl;}else//父进程{pid_t ret=waitpid(-1,NULL,0);if(ret==i)cout<<"等待成功,"<<ret<<endl;}return 0;
}

我们知道开始我们就创建了一个子进程,而创建子进程的特点就是:数据独立以写时拷贝的方式存在,代码共享。而此时子进程执行execl函数,所以子进程就替换成了ls-a-l的一个程序,此时新程序的代码数据会覆盖在物理内存上。我们知道正常情况下父子进程数据发生改变时会以写时拷贝的方式另存空间,但是代码并不会。可是此时情况特殊,所以代码同样也会以写时拷贝的方式另存空间。归根结底还是:进程具有独立性

所以回到开始,为什么execl函数之后的代码不执行?其实就是程序替换,导致原进程的代码数据被新程序的代码数据覆盖,所以后续的代码自然就没有了,更不可能被执行。


其实我们的进程切换对语言是没要求的,可以自己随意地切换成其他语言的程序,不一定只切换成同语言的程序。

程序替换总结

程序替换是指将当前运行中的进程完全替换为一个新的程序。简单来说,就是将当前进程的代码、数据和堆栈等内容替换为新程序的代码、数据和堆栈。

当一个进程执行程序替换时,原来进程的代码、数据和堆栈被新程序覆盖,然后开始执行新程序的代码。这意味着原来进程的运行状态、打开的文件、socket连接等都会丢失,并且无法恢复。新程序从main函数开始执行,其运行过程与原程序无关。


而且对于需要传环境变量的exec类系统调用函数而言,环境变量属于全局的字符指针数组类型的变量environ,而且一个进程的环境变量是源于其父进程的环境变量,也就是说子进程会继承父进程的环境变量。不仅仅是创建子进程时会继承环境变量和命令行参数,而对于进程切换时也是会继承下来的。而对于进程替换而言原进程会采用覆盖环境变量内容的方式让新的进程继承下来,也就是说如果原进程调用函数接口时传入的环境变量是自己写的环境变量的话,那么切换的新进程会将原进程的环境变量里的内容继承下来。但是如果不想覆盖式传递的话可以采用putenv(char* env_val)函数在原环境变量表里去添加新的环境变量env_val,此时就不会清空原环境变量里的内容,而是添加内容后的环境变量传递给新的进程main函数的第三个参数当中。

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

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

相关文章

栈和队列的初始化,插入,删除,销毁。

目录 题外话 顺序表和链表优缺点以及特点 一.栈的特点 二. 栈的操作 2.1初始化 2.2 栈的销毁 2.3 栈的插入 2.3 输出top 2.4 栈的删除 2.5 输出栈 题外话 顺序表和链表优缺点以及特点 特点&#xff1a;顺序表&#xff0c;逻辑地址物理地址。可以任意访问&#xff0c…

CTF-PWN-tips

文章目录 overflowscanfgetreadstrcpystrcat Find string in gdbgdbgdb peda Binary ServiceFind specific function offset in libc手工自动 Find /bin/sh or sh in library手动自动 Leak stack addressFork problem in gdbSecret of a mysterious section - .tlsPredictable …

HDMI之EDID析义篇

DisplayID Type X Video Timing Data Block 实例 F0 2A 10 93 FF 0E 6F 08 8F 10 93 7F 07 37 04 8F 10该数据来源于SHARP AQUOS-TVE23A 4K144Hz电视机的第3个EDID块(基于HF-EEODB)。 定义 解释 VTDB 1: 3840x2160 144.000009 Hz 16:9 333.216 kHz 1343.527000 MHz (RBv3,h…

python中sklearn库在数据预处理中的详细用法,及5个常用的Scikit-learn(通常简称为 sklearn)程序代码示例

文章目录 前言1. 数据清洗&#xff1a;使用 sklearn.preprocessing 中的 StandardScaler 和 MinMaxScaler 进行数据规范化。2. 缺失值处理&#xff1a;使用 sklearn.impute 中的 SimpleImputer 来填充缺失值。3. 数据编码&#xff1a;使用 sklearn.preprocessing 中的 OneHotEn…

Springboot集成JDBC

1&#xff0c;pom.xml配置jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 2&#xff0c;配置数据源信息 server:port: 8088spring:datasource:dr…

人类智能的精髓超出了统计概率

处理不确定性好坏的程度是衡量各种智能系统高低的一个重要指标。在处理不确定性时&#xff0c;智能系统需要具备推理、学习和决策的能力&#xff0c;通常使用概率和统计等方法来建模和处理不确定性&#xff0c;以便更好地应对现实世界中的复杂问题。统计概率是基于大量观察和数…

Leetcode—剑指Offer LCR 140.训练计划II【简单】

2023每日刷题&#xff08;三十三&#xff09; Leetcode—LCR 140.训练计划II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* trainingPlan(struct ListNode* head, int cnt) {str…

python自动化标注工具+自定义目标P图替换+深度学习大模型(代码+教程+告别手动标注)

省流建议 本文针对以下需求&#xff1a; 想自动化标注一些目标不再想使用yolo想在目标检测/语意分割有所建树计算机视觉项目想玩一玩大模型了解自动化工具了解最前沿模型自定义目标P图替换… 确定好需求&#xff0c;那么我们发车&#xff01; 实现功能与结果 该模型将首先…

web服务器练习---配置nginx三种虚拟主机

在做实验之前&#xff0c;大家先安装nginx服务&#xff0c;有两种安装方法&#xff1a; 1、rpm包安装&#xff08;安装过程简单&#xff0c;适用于学习阶段&#xff0c;方便测试&#xff09; 2、源码安装&#xff08;安装过程较为复杂&#xff0c;适用于生产环境&#xff09;…

IOS object-c大屏图表 PNChart 折线图 曲线图

折线图是排列在工作表的列或行中的数据可以绘制到折线图中。折线图可以显示随时间&#xff08;根据常用比例设置&#xff09;而变化的连续数据&#xff0c;因此非常适用于显示在相等时间间隔下数据的趋势。在折线图中&#xff0c;类别数据沿水平轴均匀分布&#xff0c;所有值数…

kernel32.dll下载地址分享,Kernel32.DLL文件丢失的修复指南

作为计算机用户&#xff0c;我们可能都曾遭遇过这样一条令人烦恼的错误信息&#xff1a; "程序无法启动&#xff0c;因为您的计算机中缺少Kernel32.dll"。在这种情况下&#xff0c;往往会引发一系列疑问&#xff1a; Kernel32.dll是什么&#xff1f;为什么它对我的电…

100套Axure RP大数据可视化大屏模板及通用组件库

106套Axure RP大数据可视化大屏模板包括了多种实用美观的可视化组件库及行业模板库&#xff0c;行业模板涵盖&#xff1a;金融、教育、医疗、政府、交通、制造等多个行业提供设计参考。 随着大数据的发展&#xff0c;可视化大屏在各行各业得到越来越广泛的应用。可视化大屏不再…