揭秘进程程序替换:加载器的核心原理
进程程序替换来初步了解一下进程程序替换加载器这些接口的作用为执行一个程序我们这里使用execl接口我们自己写的程序可以调用其他的程序我们调用了系统中的命令我们写的进程通过execl系统调用把系统的命令调用起来这种现象就是进程替换我们在bash使用ls命令ls命令也是进程所以应该是bash通过fork创建子进程阻塞等待这个子进程在子进程通过execl调用ls命令的程序这就是进程程序替换我们可以将这个系统调用放在子进程中使用进程替换的原理 - fork我们在调用execl系统调用之前这个进程还是我们自己提供给系统的程序进程 内核数据结构 代码数据所以此时数据和代码还属于我们自己的程序当运行execl系统调用这个函数给我们指明一个新的程序新的程序就是指明新的代码和数据所以通过execl指明一个新的程序那就把新程序的代码和数据以覆盖式的写入到数据和代码段中只替换代码设数据这个过程中PCB、虚拟地址空间、都没有变化页表映射关系可能会改变覆盖的数据代码的大小与原内存不一程序替换的过程中并没要创建新的进程只是把当前进程的代码和数据用新程序的代码数据以覆盖式的进行替换为什么程序后面部分的代码没有运行出来从execl函数开始本函数的代码和数据已经不在内存中了运行新程序的代码和数据运行完后已经进程退出即一旦程序替换成功就运行新程序代码就原始代码的后半部分已经不存在了如果进程程序替换失败了呢我们可以发现给一个错误的路径去替换程序替换失败进程就按原代码继续运行execl函数只有函数错误才会返回返回-1exec* 函数只有失败返回值没有成功返回值所以exec* 系列的函数不用做返回值判断只要返回就是失败而在execl后面的代码往往也是进程退出的语句因为execl存在的意义就是去替换程序完成某个任务而替换失败也代表着这个进程的任务失败后续直接exit(1)退出即可认识全部接口这些函数都有共享都是以exec为前缀的int execl(const *pathname,const char *argv,.../* (char *)NULL */);const *pathname-- 路径 程序名(/usr/bin/ls)作用告知进程要执行谁函数参数中...叫做可变参数列表函数传参默认是按定义的参数来传的但是我们传参的数量是不确定的就可以用可变参数列表 可以在C语言函数栈帧出了解那pathname后面的参数要怎么填写呢命令怎么写参数就怎么传ls命令在命令行上ls -a -l那么就以命令行运行格式以逗号为分隔符一个一个的传入excel(/usr/bin/ls,ls,-a,-l);所以这函数第一个参数是要知道我们要执行那个程序得到程序后考虑到程序可能有多个选项所以接下来要想怎么执行程序根据命令行输入方式传入类似把参数以链表的形式传入所以execl的l就是list的意思而我们写list链表其最后一定指向NULL此处同理函数传参最后要以NULL结尾我们知道execl会把自己的程序替换了有没有方法不替换我自己的程序让父进程安心做自己的事情让其他进程来做进程替换可以吗答案是可以我们完全可以让子进程来做程序替换不影响父进程的程序运行会不会影响父进程不会进程具有独立性数据和代码都发现写时拷贝子进程完全独立于父进程了子进程都是用自己的数据和代码而exec* 接口可以认为是加载器程序的加载实际上是进程的动态创建而我们学习了OS我们可以知道我们调用某个程序是在bash的基础上进行的也就是说bash加载程序实际上就是通过fork创建子进程在子进程替换相应的任务程序从而我们可以认为exec* 接口为加载器可以替换自己的程序吗可以只要是可以调度的进程都可以被替换我们可以在C语言中在子进程替换自己的C程序调用py文件这类脚本的文件我们调用py调用的不是脚本而是解释器所以在execl中应该是execl(/usr/bin/python3,python,other.py,NULL);bash同理execl(/usr/bin/bash,bash,other.sh,NULL);所以我们现在可以用C语言调用任何语言的程序这些程序都是进程都可以在C语言内子进程中进行进程程序替换知识不同语言的调用方式不一样验证进程程序替换时不产生新进程我们对替换的程序中做PID输出语句再在被替换的程序中对子进程被替换前做PID输出语句来看看替换前和替换后PID有没有变化可以来验证是否产生新进程可以看到进程程序替换时不产生新进程int execlp(const char *file,const char *argv,.../* (char *)NULL */);这个接口execlp其实p就是指PATH所以使用execlp替换接口我们不需要提供工作目录路径,只告诉要执行的文件名即可之后的就是和上面一样命令行如何写这里参数就这样写因为execlp会自动在环境变量PATH中查找指定的命令注意这里两个ls表达的语义是不一样的第一个表达是要执行的是谁后面的是表示要怎么执行这个程序int execv(const char *pathname,char *const argv[]);pathname参数的用法和execl用法一样execv中的v是vector(数组)参数是数组即提供一个命令行参数表就是一个指针数组所以execv的使用就是提供要调用程序的路径名称然后在调用execv之前提供一个char *const的指针数组(注意这个数组结尾也要NULL)execl与execv在传输的内容上完全一样只是传输的方式上不一样execl是链表传入execv是用数组传入的我们回想一下我们之前讲命令行参数的时候并没有讲是谁传给main函数的现在我们可以讲了父进程在通过子进程用exec接口替换程序的时候父进程如果有argv[]就用execv的形式把命令行参数传入到ls进程的main函数中其实argc是可以统计出来的所以说到底还是父进程传的int execvp(const char *file,char *const argv[]);现在看这个已经不用解释了对于参数同上面有类似file - 程序名argv[] - 命令行参数表int execvpe(const char *file,char *const argv[],char *const envp[]);相比于execvp来说execvpe多了一个参数char *const envp[]!这个参数就是环境变量我们实现一个程序用于输出程序的命令行参数和环境变量我们在父进程内通过子进程内设置一个环境变量和命令行参数通过execpe替换other程序看能否输出我们设置的环境变量和命令行参数表很明显可以我们在这里可以发现这里替换程序打印环境变量只打印父进程提供的环境变量没有打印从bash继承的系统环境变量所以使用execvpe的时候替换的程序要求使用全新的环境变量表程序接收父进程传入的环境变量表那就覆盖掉原本从父进程继承的环境变量表用最新的那想要以新增的环境变量表给子进程呢我们不使用execvpe我们子进程本来就可以获得bash继承的环境变量为什么子进程会知道父进程的环境变量父进程又没有给子进程传答案是虚拟地址空间虚拟地址空间中命令行参数和环境变量属于专属的区域子进程复制父进程的内核数据结构和代码数据子进程做程序替换替换的是子进程的代码和数据并影响环境变量区域的数据所以子进程通过虚拟地址同样可以获得父进程指向的环境变量二、其实exec接口加载新程序的时候在调用我们新程序的时exec接口底层会自动把指向环境变量的environ这个全局指针传递给新进程这里通过资料查询了解到——其实exec覆盖子进程虚拟地址空间是全覆盖的因为当前进程要变成一个全新的程序所以旧数据不能留所以环境变量区域也别清理了所以exec接口会默认自动的在传参处添加子进程的environ指针内核收到环境变量就会复制给新程序进程新进程启动environ就指向这份拷贝环境变量解决增量式传递环境变量可以了解一个新接口putenvputenv功能是新增环境变量在那个进程调用这个就在这个进程环境变量表中添加一个环境变量添加环境变量的字符串不能被销毁要在全局变量设置这个字符串那我们就是想用execvpe的方式传递新增环境变量方法如下通过循环来把要增加的环境变量添加到environ中在execvpe中传递environ全局变量(注意要extern char **environ定义告诉编译器变量在外部去链接别报错)这里传入environ其实我们使用exec接口没有使用环境变量传入编译器会自动转化成exece*传递environ综上增量添加环境变量方法通过putenv将环境变量添加到父进程自己的环境变量表中使用exec* 接口接口默认也会把父进程环境变量拷贝给新程序通过使用execvpe接口向environ中添加新环境变量在execvpe参数中传递environint execve(const char *pathname,char *const argv[],char *const envp[]);我们在上面的exec接口中可以发现少了一种exec接口execve我们可以看到execve是分开于其他接口因为这个execve是系统调用而其他的exec接口都是execve的语言封装说白了上面的那么多接口到最后都要调用execve系统调用都需要传pathnameargvenv这些参数所以我们那些不传env的exec接口没有传环境变量参数没传就默认调用environ编译器默认会补充环境变量参数有传递环境变量就传递我们提供的环境变量总结进程程序替换主要是通过调用接口实现程序的替换我们讲解了61个exec接口这里做语言级别的封装是为了面对上层替换的场景参数的不同形式有对应的接口这些接口到最后底层都会转化成execve的形式调用

相关新闻

C语言第二章

C语言第二章

一.变量1.做计算printf("1213%d",1213);2.算找零printf("100-23%d",100-23);3.为什么要引入变量每次计算时都需要输入数字,繁琐4.引入change函数int price0; printf("请输入金额(元):"); scanf("%d"…

2026/10/1 3:19:24 阅读更多 →
在 Elasticsearch 中构建上下文:AI Indices 如何使用更少的 tokens 为更智能的 agent 提供支持

在 Elasticsearch 中构建上下文:AI Indices 如何使用更少的 tokens 为更智能的 agent 提供支持

作者:来自 Elastic Kathleen DeRusso, Matt Nowzari, Apostolos Matsagkas, Peter Pisljar 将 AI agent 上下文存储在 AI Index 中,使用更少的 tokens 为更智能的 agent 提供支持。包含使用 ES|QL 和 Kibana Workflows 的分步演练。 Agent 在回答任何问题…

2026/10/2 5:51:35 阅读更多 →
Path of Building完整指南:10分钟上手流放之路离线Build规划,告别手动算伤害

Path of Building完整指南:10分钟上手流放之路离线Build规划,告别手动算伤害

Path of Building完整指南:10分钟上手流放之路离线Build规划,告别手动算伤害 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding Path of Building&am…

2026/10/1 3:55:01 阅读更多 →

最新新闻

mac-mouse-fix 的 Objective-C 代码风格指南:枚举、宏与可维护性的工程实践

mac-mouse-fix 的 Objective-C 代码风格指南:枚举、宏与可维护性的工程实践

桌面应用系统编程 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 点击查看 免费下载 本指南基于 mac-mouse-fix 仓库中的 CodeStyle.md 整…

2026/10/2 7:57:34 阅读更多 →
从零搭建AI工程能力:模型抽象、异步服务化与成本控制实战

从零搭建AI工程能力:模型抽象、异步服务化与成本控制实战

1. 从零搭建AI工程能力:为什么我劝你别一上来就调包这两年“AI工程”这个词被说得太多了,多到有点变味。招聘JD上写着“熟悉AI工程化落地”,点进去一看,要求会调三个API、会写Prompt、会用某个开源框架搭个Demo。说实话&#xff0…

2026/10/2 7:57:33 阅读更多 →
DeepSeek大模型企业应用实战:选型、部署、微调与避坑指南

DeepSeek大模型企业应用实战:选型、部署、微调与避坑指南

最近被问得最多的一句话就是:DeepSeek大模型到底能不能落到企业的真实业务里?我手上刚好整理过一份面向企业应用实践的150页PPT资料,里面把从技术选型、API接入、私有化部署、场景设计到微调训练的内容全部串了一遍。这篇文章就是基于那份内容…

2026/10/2 7:57:33 阅读更多 →
openrig:用YAML统一管理claude code与codex的AI编程工具配置

openrig:用YAML统一管理claude code与codex的AI编程工具配置

1. 从“openrig”这个名字说起:它到底想解决什么问题第一次看到openrig这个词,我脑子里蹦出来的第一反应是“open”加“rig”——一个开放的、可拼装的“装备架”。事实也确实八九不离十。在当下这个 AI 编程助手满天飞的阶段,claude code、c…

2026/10/2 7:57:33 阅读更多 →
AI工程从零构建:GPU感知、可观测性与容器化部署实战

AI工程从零构建:GPU感知、可观测性与容器化部署实战

1. 这不是“搭积木”,而是亲手锻造AI系统的底层逻辑 “ai-engineering-from-scratch”这个标题,乍看像一句技术口号,但在我带过二十多个工业级AI项目、亲手从零写过三套模型服务框架、拆解过十七家大厂推理引擎源码之后,我越来越…

2026/10/2 7:57:33 阅读更多 →
Example Voting App:一个覆盖 Docker、Compose、Swarm 与 Kubernetes 的多容器分布式投票应用实战指南

Example Voting App:一个覆盖 Docker、Compose、Swarm 与 Kubernetes 的多容器分布式投票应用实战指南

示例工程云原生后端 【免费下载链接】example-voting-app Example distributed app composed of multiple containers for Docker, Compose, Swarm, and Kubernetes 项目地址: https://gitcode.com/GitHub_Trending/ex/example-voting-app 点击查看 免费下载 本指南…

2026/10/2 7:56:32 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →