您的位置:首页 > 其它

进程的创建与可执行程序的加载

2013-05-30 19:55 323 查看
 

 刘云岭    SA12226438
【实验二】进程的创建与可执行程序的加载 
参考进程初探 编程实现fork(创建一个进程实体) -> exec(将ELF可执行文件内容加载到进程实体) -> running program
参照C代码中嵌入汇编代码示例及用汇编代码使用系统调用time示例分析fork和exec系统调用在内核中的执行过程
注意task_struct进程控制块,ELF文件格式与进程地址空间的联系,注意Exec系统调用返回到用户态时EIP指向的位置。
动态链接库在ELF文件格式中与进程地址空间中的表现形式

实验内容:
一、fork()函数与exec()函数的分析
fork:copy当前进程创建一个新的进程;     
exec:读取可执行文件并将其载入地址空间开始运行。
   1、fork过程
    一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。过程如下
(1)创建进程都是通过调用do_fork函数完成,其中提供了很多参数标志来表明进程创建的方式;
(2)copy_process里面通过父进程创建子进程;
(3)task_struct根据父进程创建子进程内核栈和进程描述符,创建进程copy_process之后并未执行,返回到do_fork中,将新创建进程加入到运行队列中等待被执行;
(4)进程终结时内核释放其所占有的资源,并告诉父进程,更新父子关系。调用exit终结进程,进程被终结时通常最后都要调用do_exit来处理。
2、exec过程
    exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件,如果不是可以执行的文件,那么就解释成为一个shell文件。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。具体过程如下:
  (1)将可执行文件的首部拷贝至内存;
  (2)根据动态链接程序路径名将共享库对应函数映射到内存;
  (3)释放原进程的内存描述符、线性区描述符、所有页框;
  (4)选择线性区的布局;
  (5)为可执行文件的代码段、数据段以及动态链接程序的代码段、数据段分      别进行内存映射;
  (6)修改内核态堆栈中eip、esp寄存器的值,使其分别指向程序的入口点以及新的用户态堆栈顶并返回;

二.注意task_struct进程控制块,ELF文件格式与进程地址空间的联系,注意Exec系统调用返回到用户态时EIP指向的位置。
    task_struct进程控制块中的mm字段所指向的mm_struct结构描述了进程地址空间的信息,包括代码段、数据段、堆段、栈段所在地址空间里的起始和结束地址等信息。

ELF文件格式中的 ELF头部、段头部表对应进程地址空间中的代码段,在加载可执行文件时,会把它们映射到进程地址空间中的代码段区域。ELF文件格式中的 .data对应进程地址空间中的数据段,在加载可执行文件时,会把它们映射到进程地址空间的数据段区域。

三.动态链接库在ELF文件格式中与进程地址空间中的表现形式
    动态链接库在ELF文件中对应着.dynamic段所包含的信息:包括动态链接器所需要的相关信息,比如依赖于哪些共享对象(例如libc.so)、动态链接符号表位置。

动态链接库最后被映射到进程地址空间的共享库区域段。

四.实例分析
    代码一:

结果:
   
   代码二:
   

}
结果:

代码三:

结果:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  行业数据