进程的描述和进程的创建

Posted on 2016-03-31 13:47  20135131张潇月  阅读(291)  评论(1编辑  收藏  举报

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

进程描述符task_struct数据结构

进程描述符提供了内核所需要了解的内核信息。task_struct数据结构十分庞大。

Linux的进程状态和与操作系统原理中描述的进程状态似乎有所不同。本质上是一样的,就绪态,运行态,阻塞态。

所有的进程状态

进程标识符

进程的链表

它是一个双向链表,把所有的进程连接起来。链表是可以独立进行操作的,

每个进程有自己独立的进程地址空间。

父子关系

这就是进程中父子关系的管理

ptraced是调试用的。

进程的创建

fork系统调用在父进程和子进程各返回一次,这样就变成了两个进程。通过这个fork()系统调用就可以在用户态创建一个进程。

正常的系统调用:

调用fork()的时候

 

父进程还是和一般正常调用一般返回,而fork产生的子进程在内核里面返回。

fork、vfork、clone都可以创建新的进程,而且都是通过调用do_fork来实现进程的创建。

创建新进程是通过复制当前进程来实现的。

Linux通过复制父进程来创建一个新进程,那么为我们理解这个过程提供一个理想的框架:

系统调用内核处理函数sys_fork、sys_vfork、sys_clone。

dup task struct——复制task struct。

子进程

子进程是从return_from_fork开始执行的,然后挑战到syscall_exit,到系统调用中返回。

实验

启动MenuOS

在新窗口中启动调试gdb

设置断点

在MenuOS中执行fork,就会发现fork函数停在了父进程中

继续执行之后,停在了do_fork的位置。然后n单步执行,依次进入copy_process、dup_task_struct。按s进入该函数,可以看到dst = src(也就是复制父进程的struct)

在copy_thread中,可以看到把task_pg_regs(p)也就是内核堆栈特定的地址找到并初始化

到了159、160行的代码就是把压入的代码再放到子进程中:

*children = *current_pt_regs();
childregs->ax = 0;

164行,是确定返回地址

p->thread.ip = (unsigned long) ret_from_fork;

Copyright © 2024 20135131张潇月
Powered by .NET 8.0 on Kubernetes