- 浏览: 84380 次
文章分类
- 全部博客 (136)
- 我的技术资料收集 (98)
- 具体技术 (1)
- 的技术资料收集 (4)
- All Articles (1)
- 机器学习 Machine Learning (1)
- 网络编程 (1)
- java (2)
- ava (1)
- 零散技术 (1)
- C# (3)
- 技术资料收集 (1)
- CQRS (1)
- 数据库技术(MS SQL) (1)
- .Net微观世界 (1)
- Oracle SQL学习之路 (1)
- C/C++ (1)
- JS/JQ (1)
- Js封装的插件/实例/方法 (2)
- 敏捷个人 (2)
- Javascript (1)
- 程序设计---设计模式 (1)
- Bug (1)
- 未知分类 (1)
- 程序设计 (1)
- Sharepoint (1)
- Computer Graphic (1)
- IT产品 (1)
- [06]JS/jQuery (1)
- [07]Web开发 (1)
- .NET Solution (1)
- Android (3)
- 机器学习 (1)
- 系统框架设计 (1)
- Others (1)
- 算法 (1)
- 基于Oracle Logminer数据同步 (1)
- 网页设计 (1)
- 原创翻译 (1)
- EXTJS (1)
- Jqgrid (1)
- 云计算 (1)
最新评论
根据前两篇博文中的实验:
现对进程的创建和可执行程序的加载过程总结如下:
一:进程地址空间的组成及相关数据结构
Linux为每个进程都维持了一个独立的虚拟地址空间,进程地址空间又被分为几个虚拟内存区域:代码段、数据段、堆段、栈段、共享库段。进程地址空间中的任何有效地址都只能位于唯一的区域,这些区域不能相互覆盖。通过mmap/munmap函数,内核可以创建/删除一个虚拟内存区域。
主要的数据结构有:
task_struct : 进程描述符结构,定义在<linux/sched.h>文件中,描述了该进程打开的文件、进程的地址空间、进程的状态等信息。
mm_struct :进程虚拟内存描述符,定义在<linux/sched.h>文件中,该结构包含了和进程地址空间相关的全部信息。
vm_area_struct:虚拟内存区域描述符,定义在<linux/mm.h>文件中,该结构体描述了指定地址空间内连续区间上的一个独立的内存范围(比如进程用户空间栈、代码段、数据段等)。
三个结构之间的关系:
task_struct 中的一个 字段 mm 指向当前进程的虚拟地址空间描述符 mm_struct , mm_struct中的字段 mmap 指向一个vm_area_struct组成的链表,其中每个vm_area_struct 都描述了当前虚拟地址空间的一个区域。
这里涉及的一些关键结构的具体信息可查看我前面的博文 :Linux进程地址空间之初探:一
二:fork 和 exec 函数及加载器的执行过程
fork( )函数通过拷贝当前进程创建一个子进程,子进程与父进程的区别仅仅在在于PID、PPID和某些资源和统计量(例如,挂起的信号,它没必要被继承),Linux中fork是通过clone( )实现的,clone( )再调用do_fork( )。
执行过程:
1)为新进程创建一个内核栈、thread_info结构和task_struct 结构,这些结构的值与当前进程的值相同。此时子进程和父进程的描述符是完全相同。
2)子进程开始使自己与父进程区别开来。进程描述符内的许多成员要被清零或设为初始值。
3)子进程的状态被设置为TASK_UNINTERRUPTIBLE,以保证不会透入运行。
4)设置task_struct中的相应flags标志,例如权限
5 ) 为新进程分配一个有效PID
6)根据传递给clone( )的参数标志进行拷贝或者共享打开的文件、文件系统信息、进程地址空间和命名空间等。
7)最后返回子进程的PID。
exec( )函数:exec函数在当前进程的上下文中加载并运行一个新的程序,只有在出错的情况下exec 函数才会返回到调用程序中,所以与fork函数调用一次返回两次不同,exec调用一次并从不返回。
exec( )执行过程:
1)删除当前进程虚拟地址空间的用户部门已经存在的区域结构。
2)加载可执行文件,用可执行文件中的内容覆盖当前进程地址空间相应区域
3)设置程序计数器即eip中的值,使它指向新的代码区的入口点,调用启动代码,启动代码设置栈,控制传给新程序的主函数。
其中加载可执行文件的执行过程如下:
1 )启动加载器,加载器删除子进程现有的虚拟地址段
2 )加载器根据可执行目标文件中的段头部表信息,创建一组新的代码段、数据段、堆段和栈段。新的堆、栈段初始化为零。代码段和数据段映射为可执行文件的代码段和数据段。
3)根据可执行文件 ELF 中的.interp段查找动态链接器ld.so的路径名,动态链接器实际上也是一个共享对象,加载器同样通过映射的方式将它加载到进程的地址空间。然后把控制权交给动态链接器的入口地址(与可执行文件一样,共享对象也有入口地址),当动态链接器得到控制权后,进行一系列初始化操作,然后根据可执行文件ELF中.dynamic段,这个段里保存了动态链接器所需要的相关信息,比如依赖于哪些共享对象(例如libc.so)、动态链接符号表位置、动态链接重定位表的位置、共享对象初始化代码的地址等信息,根据它们查找和加载可执行文件所依赖的共享对象,并映射到进程地址空间的共享区域中。
4)当所有动态链接工作完成以后,动态连接器会将控制权交给可执行文件的入口地址,即跳转到可执行文件的_start 启动代码并调用新程序中的main函数开始执行。
这里提到的 .interp 、.dynamic、段头部表的查看方法及具体信息可查看我上篇博文:Linux进程地址空间之初探:二
三:task_struct进程控制块,ELF文件格式与进程地址空间的联系
task_struct进程控制块中的mm字段所指向的mm_struct结构描述了进程地址空间的信息,包括代码段、数据段、堆段、栈段所在地址空间里的起始和结束地址等信息。
ELF文件格式中的 ELF头部、段头部表、.init、.text、.rodata段对应进程地址空间中的代码段,在加载可执行文件时,会把它们映射到进程地址空间中的代码段区域。
ELF文件格式中的 .data、.bss段 对应 进程地址空间中的 数据段,在加载可执行文件时,会把它们映射到进程地址空间的数据段区域。
具体的对应关系图请见 上篇博文:Linux进程地址空间之初探:二
四:动态链接库在ELF文件格式中与进程地址空间中的表现形式
发表评论
-
C#WebBrowser控件使用教程与技巧收集--苏飞收集 - sufeinet
2013-06-28 12:07 1073原帖地址:http://www.cnblogs.com/suf ... -
我要喷一个自认为很垃圾的网站架构 - 老赵【苏州】
2013-06-28 12:01 1134原帖地址:http://www.cnblogs.com/lao ... -
[翻译] Oracle Database 12c 新特性Multitenant - Cheney Shue
2013-06-28 11:43 624原帖地址:http://www.cnblogs.com/ese ... -
memcahd 命令操作详解 - 阿正-WEB
2013-06-28 11:37 475原帖地址:http://www.cnblogs.com/azh ... -
面向过程的代码符合大众的思维方式吗? - 史蒂芬.王
2013-06-27 10:28 597原帖地址:http://www.cnblogs.com/ste ... -
面向过程的代码符合大众的思维方式吗? - 史蒂芬.王
2013-06-27 10:28 560原帖地址:http://www.cnblogs.com/ste ... -
RPG游戏之组队测试 - zthua
2013-06-27 10:22 560原帖地址:http://www.cnblogs.com/zth ... -
IT人们给个建议 - SOUTHER
2013-06-26 14:06 526原帖地址:http://www.cnblogs.com/sou ... -
Java向前引用容易出错的地方 - 银河使者
2013-06-26 14:00 497原帖地址:http://www.cnblogs.com/nok ... -
使用Func<T1, T2, TResult> 委托返回匿名对象 - 灰身
2013-06-26 13:54 801原帖地址:http://www.cnblo ... -
【web前端面试题整理03】来看一点CSS相关的吧 - 叶小钗
2013-06-25 10:45 788原帖地址:http://www.cnblogs.com/yex ... -
Windows 8 动手实验系列教程 实验6:设置和首选项 - zigzagPath
2013-06-25 10:27 624原帖地址:http://www.cnblogs.com/zig ... -
闲聊可穿戴设备 - shawn.xie
2013-06-25 10:21 568原帖地址:http://www.cnblo ... -
CentOS下Mysql安装教程 - 小学徒V
2013-06-23 15:24 612原帖地址:http://www.cnblogs.com/xia ... -
vmware安装ubuntu12.04嵌套安装xen server(实现嵌套虚拟化) - skyme
2013-06-23 15:18 840原帖地址:http://www.cnblogs.com/sky ... -
之前专门为IE6、7开发的网站如何迁移到IE10及可能遇到的问题和相应解决方案汇总 - 海之澜
2013-06-23 15:12 956原帖地址:http://www.cnblogs.com/wuz ... -
Android学习笔记--解析XML之SAX - 承香墨影
2013-06-23 15:01 413原帖地址:http://www.cnblo ... -
SQL Server 性能优化之——T-SQL TVF和标量函数
2013-06-19 09:32 676原帖地址:http://www.cnblogs.com/Boy ... -
Nginx学习笔记(二) Nginx--connection&request
2013-06-19 09:26 671原帖地址:http://www.cnblogs.com/cod ... -
从郭美美霸气侧漏看项目管理之项目经理防身术
2013-06-19 09:20 504原帖地址:http://www.cnblogs.com/had ...
相关推荐
这种方式常用于动态加载可执行文件,例如在shell脚本中执行命令。 三、进程间通信(管道) 进程间通信(IPC, Inter-Process Communication)是操作系统中实现不同进程间数据交换的关键技术。管道是一种半双工通信...
总结来说,QT通过QProcess调用外部可执行程序并嵌入到主窗口中的步骤包括: 1. 创建QProcess对象。 2. 启动外部程序并设置工作目录。 3. 连接QProcess的信号到相应的槽,以便处理输出。 4. 在槽函数中读取并显示输出...
- `CreateProcess`:这是创建新进程的主要函数,它不仅启动一个新进程,还会加载指定的可执行文件。 - `OpenProcess`:用于获取对已存在进程的访问权限,以便进一步监控或控制。 - `GetProcessId`:获取进程的...
在这个过程中,操作系统会将进程创建,并将程序加载到内存中。 8. 代码执行的概念与作用 代码执行是程序执行的过程,程序会将代码加载到内存中,并执行代码。在这个过程中,程序会将代码加载到内存中,并执行代码,...
main函数是可执行程序的入口点,其原型形式如下:`int main(int argc, char argv, char envp);`或者:`int main(int argc, char *argv[], char *envp[]);`其中,`argc`指定参数个数,参数列表中第一个总是命令名(可...
这个函数负责加载可执行文件,初始化进程和线程,为新进程分配内存,以及设置进程和线程的属性。以下是`CreateProcess`的基本调用格式: ```cpp BOOL CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout...
1. **程序加载**:操作系统读取程序的可执行文件(如.exe或.dll),通常是PE(Portable Executable)格式的文件,到内存中。 2. **地址空间初始化**:为进程分配虚拟内存空间,包括代码段、数据段、堆和栈。 3. **...
- 进程是动态的,代表程序在内存中的执行实例,而程序是静态的,是存储在磁盘上的可执行代码。 - 进程包含程序的执行上下文,包括程序计数器、栈、全局变量等。 4. **进程的优点与缺点**: - 优点:支持并发执行...
### 进程与程序:编写命令解释器sh ...通过以上内容的学习,我们可以更好地理解进程和程序的概念,以及如何使用Unix系统中的Shell来管理和执行程序。这对于深入理解操作系统工作原理和进行系统级编程具有重要意义。
在Windows操作系统中,有时为了软件的安全性和便携性,开发者会尝试将可执行文件(exe)嵌入到主程序的资源中,然后在程序运行时动态地从资源中加载到内存并执行。这种方式避免了单独分发多个文件,也可以防止恶意...
DLL是Dynamic Link Library的缩写,它是一种可执行文件格式,包含可由多个程序同时使用的代码和数据。通过进程注入,我们可以将一个DLL加载到另一个正在运行的进程中,使得该DLL的函数和资源可以在目标进程中使用。 ...
这个函数允许程序启动一个新的可执行文件,并为其创建一个新进程和线程。它接收一系列参数,如应用程序名称、命令行参数、进程和线程的安全属性等,然后执行一系列操作,包括加载映像文件、分配内存、设置初始堆栈和...
当我们谈论在C#中使用进程加载应用程序时,我们通常是指利用System.Diagnostics命名空间中的Process类来启动、控制或与另一个应用程序交互。这个过程可以分为几个关键步骤,包括创建Process对象、配置启动信息以及...
**模块** 在Windows程序中,通常指的是可执行文件(.exe)和动态链接库(.dll)。模块包含了进程运行所需的代码和数据。当进程启动时,它的主模块(通常是.exe文件)会被加载到内存中,随后可能根据需要加载其他.dll...
`CreateProcess`函数是Windows API的一部分,它负责初始化新进程的内存空间,加载可执行文件,并执行该文件的入口点。其原型如下: ```cpp BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine...
这通常是为了避免注册过程中的权限问题或避免对系统注册表造成过多修改,从而提高程序的可移植性和稳定性。 【标签】:“大漠”标签明确了我们的讨论是围绕大漠插件展开的。大漠插件由一系列API组成,可以实现对...
`CreateProcess`是Windows API中的一个关键函数,它负责启动新的进程并可选地创建新的线程。这个函数提供了对新进程的详细控制,包括进程的启动参数、工作目录以及环境变量等。在创建进程时,我们可以通过指定`...
在深入探讨如何在Android环境中调用二进制可执行程序之前,首先需要理解Android系统的基本架构以及它与传统Linux系统之间的区别。Android基于Linux内核构建,因此支持许多与Linux相似的功能,比如可以运行二进制可...
比如,我们可以在创建了子进程后,使用`exec()`来加载并运行一个新的可执行文件,这样子进程就不再是父进程的副本,而是执行了新的程序。 创建孙子进程的过程通常涉及以下步骤: 1. 父进程调用`fork()`,创建子进程...
1. **进程创建**:使用`fork()`函数可以创建一个新的进程。`fork()`返回值为0表示子进程,非零值表示父进程,这样我们就能区分父子进程,并进行不同的操作。 2. **进程执行**:在创建进程后,可以使用`exec()`系列...