news 2026/5/26 22:42:44

【 linux 】理解环境变量和虚拟地址空间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【 linux 】理解环境变量和虚拟地址空间

正因为你有能力跨越,这个考验才会降临


目录

1. 初始环境变量

2. 环境变量表与命令行参数表

3. 环境变量的查看

4. 虚拟地址空间

4.2 写时拷贝(COW)

4.2 缺页异常


1. 初始环境变量

环境变量是操作系统运行环境的一些参数

env可以查看所有的环境变量,unset删除环境变量,export添加环境变量,echo$查看某一个环境变量。其中env是系统级的命令,echo,set,export是shell内置的命令,getenv,setenv等是语言层的标准定义。

常见的环境变量有PATH,可执行文件的搜索路径列表。HOME当前用户主目录路径。PWD当前工作目录的绝对路径。还有USER,SHELL等等。

父进程的环境变量可以被子进程继承

当进程退出时,内存中的数据被清理,新增的环境变量自动被回收,这也进一步说明进程是独立的

2. 环境变量表与命令行参数表

每个进程都要维护两张表,命令行参数表和环境变量表。父进程创建子进程时,子进程会继承这两张表。命令行参数表是一个字符串数组,以NULL结尾,通常有两个参数argv和argc。argv是数组名,argc是数组大小,数组存储进程运行时指令与配置。环境变量表传递全局上下文信息给子进程使用。

主函数main其实也是有argv和argc这两个默认参数的,当执行文件./test时,argv[0]存储的就是./test

3. enviorn

可以用getenv查看,用const char*的变量接收,也可以用environ访问

environ是一个全局指针变量,指向一个以NULL结尾的字符串数组,使用时需要加上extern声明

environ可以遍历整个数组,拿到完整的“key=value”,

#include <stdio.h> extern char **environ; // ⚠️ 必须手动声明 int main() { for (char **ep = environ; *ep != NULL; ep++) { printf("%s\n", *ep); // 输出格式: KEY=VALUE } return 0; }

每个进程都有自己的environ,指向各自独立的内存区域,并且会进行实时更新(envp不会)

进程在创建好后会让environ直接指向内核在进程启动时放置在栈上的那块原始内存。

┌─────────────────┐ ← 高地址 │ envp strings │ ← 内核 execve() 放在栈上的原始数据 │ "PATH=/bin" │ │ "HOME=/root" │ ├─────────────────┤ │ argv pointers │ ├─────────────────┤ │ argc │ ← main(argc, argv, envp) 的参数来源 └─────────────────┘ ← 低地址 ↑ environ = &envp[0] ← 全局指针直接指向这里,零拷贝!

setenv首次修改时会malloc一块新的堆内存,将现有环境变量拷贝进去,加上新变量,然后更新environ指针指向这块新的内存,后续修改直接在堆上realloc/调整

putenv和setenv的不同:

当putenv(char* string)时,ibc 内部大致执行以下逻辑:

  1. 扫描当前environ数组,查找是否存在同名 KEY。
  2. 如果找到:直接将environ[i] = string;(替换旧指针)。
  3. 如果没找到:将string追加到environ数组末尾(必要时realloc扩容environ指针数组本身),然后补上NULL终止符。

所以putenv是很危险的,如果原字符串指针作用域结束或者free了会产生未定义行为,setenv内部是malloc和strcpy深拷贝,更加的安全,建议优先使用setenv

4. 虚拟地址空间

我们平时说的栈,堆等程序内存空间都不是物理内存,而是虚拟地址空间

一个进程,一个虚拟地址空间,一套页表,页表用来做虚拟和地址的映射

4.2 写时拷贝(COW)

写时拷贝是一种资源优化管理策略,当多个调用者请求相同资源时,系统会让他们共享同一份资源,当某个调用者试图修改资源时,系统才会为他单独复制一份副本修改

当父进程创建子进程时, 内核仅复制页表,让父子进程指向同一块物理内存并标记为只读。一旦某方尝试写入,CPU 触发缺页异常,内核才分配新内存并复制数据

程序申请内存大概分为3步

1.在虚拟地址空间中申请指定大小的空间

2.加载程序,申请物理内存

3.页表进行映射

所以,本质上物理内存是没有0x112233这样一串的数字的,一切的一切都是操作系统为了用户使用方便而包装设计的。虚拟地址的区域划分实际上就是一个结构体

struct mm_struct { long code_start; long code_end; long init_start,init_end; long unit_start,unit_end; ... }

虚拟地址空间的意义

1. 将地址从“无序”变“有序”

2.进程管理和内存管理,进行一定程度的解耦合

3. 地址转换的过程,对地址和操作判定,保护物理内存。这一步主要是通过页表权限和缺页异常来实现的,我们都知道字符串常量不能修改,是因为页表对应的权限为只读,所以无法访问物理内存进行写操作,缺页异常是操作系统的一种机制,当CPU试图访问一个虚拟地址时,如果MMU(内存管理单元)在页表中找不到有效的物理映射或者找到了映射但权限不足,CPU就会抛缺页异常

4.2 缺页异常

缺页异常分软异常和硬异常,软异常通常就是COW,硬异常指页面不在物理内存而在磁盘上,需要从磁盘上读入页面。

CPU 执行访存指令 ↓ MMU 查页表 → 发现无效/权限不足 ↓ CPU 抛出缺页异常,陷入内核态 ↓ OS 检查异常原因 + 虚拟地址 ↓ ┌──────────────┬──────────────┬──────────────┐ │ COW 写入 │ 页面在磁盘 │ 非法访问 │ │ │ │ │ │ 分配新物理页 │ 分配物理页 │ 发送 SIGSEGV │ │ 复制原页内容 │ 从磁盘读入 │ 杀死进程 │ │ 更新页表W=1 │ 更新页表 │ │ └──────────────┴──────────────┴──────────────┘ ↓ 返回用户态,重新执行刚才失败的指令

缺页异常也是虚拟内存实现所有功能:按需分页,写时拷贝,内存交换,内存映射文件,动态栈增长的基础

缺页异常也是有代价的,硬缺页需要数百万个CPU周期,高性能程序要尽量避免硬缺页

希望你能有所收获 Thanks♪(・ω・)ノ

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 22:42:33

一个简单的签到逻辑漏洞分享

1.小程序签到页面&#xff0c;连bp2.找到签到流量包3.尝试修改日期&#xff0c;不知道date可控不可控啊说明有一个date参数可控&#xff0c;尝试修改到其他日期&#xff0c;发现也可以成功签到4.爆破模块爆破日期原理

作者头像 李华
网站建设 2026/5/26 22:41:42

藜麦片哪个品牌好

在寻找优质藜麦片供应商时&#xff0c;消费者往往会关注品牌实力、产品特色和市场口碑等因素。今天就为大家推荐山西华启顺食品科技有限责任公司&#xff08;以下简称“华启顺”&#xff09;。品牌实力强劲华启顺成立于2018年1月&#xff0c;注册资本金1000万元。公司地处“中国…

作者头像 李华
网站建设 2026/5/26 22:38:37

智能一体化系统技术实施方案

智能一体化系统技术实施方案 第1章项目概述 1.1项目背景 在数字经济深度渗透的2026年,企业数字化转型进入攻坚阶段,数据量呈爆发式增长,传统系统架构面临算力不足、数据孤岛、业务响应滞后等核心痛点,难以满足现代化业务的智能化、高效化、安全化需求。当前,各行业数字…

作者头像 李华
网站建设 2026/5/26 22:33:08

如何让AI成为生产力工具——判断力是最后的拼图

一、AI的现状&#xff1a;火热&#xff0c;但还没成为生产力工具当前AI很火。大模型能写诗、能画画、能聊天、能编程&#xff0c;展现出惊人的能力。但有一个尴尬的事实&#xff1a;AI还没有真正成为生产力工具。什么叫“生产力工具”&#xff1f;不是“能帮忙”&#xff0c;而…

作者头像 李华
网站建设 2026/5/26 22:30:07

随机数值线性代数在大规模矩阵计算中的应用与优化

1. 随机数值线性代数&#xff08;RNLA&#xff09;的核心价值与技术原理随机数值线性代数&#xff08;Randomized Numerical Linear Algebra, RNLA&#xff09;正在重塑我们处理大规模矩阵计算的方式。作为一名长期从事高性能计算的工程师&#xff0c;我见证了RNLA如何从理论走…

作者头像 李华
网站建设 2026/5/26 22:28:59

基于SCCA-RMP的属性网络异常检测:融合结构与属性视图的鲁棒方法

1. 项目概述与核心挑战在网络安全、金融风控和社交平台内容审核这些我们每天都要打交道的场景里&#xff0c;有一个核心任务变得越来越关键&#xff1a;如何从海量的、相互关联的数据中&#xff0c;精准地揪出那些“行为怪异”的个体&#xff1f;这就是异常检测。传统上&#x…

作者头像 李华