Linux内核创建一个新进程的实验
陈铁 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核对进程管理是操作系统的重要任务之一。此次实验就是了解内核创建一个新进程的大致过程。为了简单,使用fork再用户态创建一个进程。代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char * argv[]) { int pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */ fprintf(stderr,"Fork Failed!"); exit(-1); } else if (pid == 0) { /* child process */ printf("This is Child Process!\n"); } else { /* parent process */ printf("This is Parent Process!\n"); /* parent will wait for the child to complete*/ wait(NULL); printf("Child Complete!\n"); } }
在虚拟机环境中运行情况如下图:
以下使用gdb调试一下,在进程创建过程中的几个关键函数出设置断点。
在系统启动过程走了些弯路,设置断点的这几个函数都是系统创建进程所必须的关键部分,所以启动过程中do_fork,copy_process,copy_thread不断的多次出现,我只好暂时使断点失效,才让menuos顺利启动到命令提示符。disable breakpoints 1 2 3 4 5 6.
执行fork命令,停在了断点SyS_clone处,单步执行,定在了断点do_fork处。经过几行代码,
p = copy_process(clone_flags, stack_start,stack_size,chile_tidptr, NULL,trace);
停在断点copy_process.在执行几行代码,如下:
p = dup_task_struct(current);
继续执行,断点arch_dup_task_struct停住。
连续n命令后可以看到子进程的初始化过程:
程序执行断在copy_thread后如下:
执行finish,及continue命令,进入了子进程执行的起点ret_from_fork.
执行c命令,主要过程基本结束。
总结,创建一个新进程在内核中的执行过程大致如下
1.使用系统调用SyS_clone(或fork,vfork)系统调用创建一个新进程,而且都是通过调用do_fork来实现进程的创建;
2.Linux通过复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈;
3.要修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread
4.p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
本文出自 “StudyPark” 博客,请务必保留此出处http://swordautumn.blog.51cto.com/1485402/1630810
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。