对于Linux系统是如何创建一个新进程的,关于fork函数又是怎样具体实现系统调用的,我们通过这次实验来做一个初步的了解。

在做实验前我们要先了解下fork函数具体完成了哪些功能,fork函数是创建一个子进程,但是子进程是处于就绪态的,它需要被调度才能进入运行态。而fork函数对应的系统调用为sys_clone,下面我们通过用gdb跟踪sys_clone来了解Linux系统是如何创建一个新进程的。

首先我们需要在sys_clone处设置一个断点来观察系统的运行过程,



我们可以看到,此时系统即便输入了fork指令,但是系统并未进行系统调度,接下来我们再通过list指令和单步调试来继续跟踪,



我们可以看到系统通过条件编译进入系统调用,并在内核态进行调度。

接着我们在do_fork处设置断点来继续观察,


通过do_fork函数我们可以看到系统主要是完成对父进程的一些标志的复制,以及设置子进程堆栈的起始和尺寸。

接下来在copy_process处设置断点,继续跟踪。


系统通过这个函数完成了对父进程的复制,接下来要做的就是复制线程了,所以我们在copy处设置断点来继续追踪。



从这里我们可以看到,系统开始复制寄存器中的值以及父进程的环境,并开始设置新进程的一些值(比如pid)以从父进程中分离出去。接着我们在ret_from_fork处设置断点来继续跟踪。顺便提一句,从ret_from_fork之后,子进程便开始执行了,所以我才把断点设在那里。



通过单步执行,我们继续观察可以看到,系统把堆栈指针都指向了新进程的寄存器,而新进程的寄存器的值都从父进程那继承过来的,并且新进程是处于就绪态的,然后新进程开始设置它自己的pid号。





之后便是执行do_fork函数,完成了新进程的创建,再之后通过ret_from_fork函数让新进程开始运行,此时可以看到系统显示了结果。



实验总结:

通过这次实验,我们可以看到Linux系统创建一个新进程的全过程,创建一个新进程需要通过内核调用sys_clone来完成,大体的过程便是先对父进程的数据和环境进行复制,然后修改新进程的一些属性,比如pid号等,之后通过do_fork函数和ret_from_fork函数完成对新进程的创建以及运行。


作者:叶涛

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000


GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐