张文俊 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1、进程的描述

进程控制块PCB——task_struct

为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符(即task_struct)提供了内核所需了解的进程信息。

父子进程关系管理:

这是CPU状态,在进程上下文切换的过程中,起到关键作用:

2、进程的创建

进程的创建概览和fork一个进程的用户态代码

以fork一个子进程的代码为例:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. int main(int argc, char * argv[])
  5. {
  6. int pid;
  7. /* fork another process */
  8. pid = fork();
  9. if (pid < 0)
  10. {
  11. /* error occurred */
  12. fprintf(stderr,"Fork Failed!");
  13. exit(-1);
  14. }
  15. else if (pid == 0)
  16. {
  17. /* child process */
  18. printf("This is Child Process!\n");
  19. }
  20. else
  21. {
  22. /* parent process  */
  23. printf("This is Parent Process!\n");
  24. /* parent will wait for the child to complete*/
  25. wait(NULL);
  26. printf("Child Complete!\n");
  27. }
  28. }

可用fork系统调用在父进程和子进程各返回一次。在fork之后,这段代码实际上就变成了两个进程。

理解进程创建过程复杂代码的方法

系统调用回顾:

创建一个新进程在内核中的执行过程

  • fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;

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

    • 复制一个PCB——task_struct

      1. err = arch_dup_task_struct(tsk, orig);
    • 要给新进程分配一个新的内核堆栈

      1. ti = alloc_thread_info_node(tsk, node);
      2. tsk->stack = ti;
      3. setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈
    • 要修改复制过来的进程数据,比如pid、进程链表等等都要改改吧,见copy_process内部。

  • 从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?

这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process

  1. *childregs = *current_pt_regs(); //复制内核堆栈
  2. childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
  3. p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
  4. p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

浏览进程创建过程相关的关键代码

以上为复制数据结构部分代码,dup_task_struct。这段代码相对简单,就是将src其中内容赋值给dst。

以上为alloc调用,它功能就是生成了两个页面。

重点还是看copy_thread的功能,pt_regs获取了pid指向的堆栈内信息,比如栈底等内容。

这是父进程对已有堆栈数据的copy,拷贝内核堆栈数据和指定新进程的第一条指令地址。

因为子进程的返回值为0,所以copy时还需要修改一下内核栈内压入的。

子进程是从哪里开始执行的?

子进程是从这个位置开始执行的,就是fork返回值被得到的时候。

对pt_regs内容进行查看,可以看到其中包含int指令和SAVE_ALL压到内核栈的内容。只复制了i32的相关内容。

从entry_32中,可以找到ret_from_fork的函数代码部分。

会跳到syscall_exit部分继续执行。正常返回到用户态。

使用gdb跟踪创建新进程的过程

如果用实验楼环境,首先需要rm menu -rf 删除原先menu 然后clone一份新的。

然后进入menu后,mv test_fork.c test.c,把test.c覆盖掉。

然后make rootfs,编译出来。

可以发现fork被进入到menu里。

然后使用gdb调试,使用-s -S。

然后设置断点:b sys_clone 和 b do_fork 和 b dup_task_struct 和 b copy_process 和 b copy_thread 和 b ret_from_fork

然后进行n单步调试。

可以看到子进程执行的起点。

3、总结

linux 系统创建进程都是用 fork() 系统调用创建子进程。

由 fork() 系统调用创建的新进程被称为子进程。

该函数被调用一次,但返回两次。

如果 fork()进程调用成功,两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程号。

"Linux内核分析"第六周实验报告的更多相关文章

  1. 《Linux内核分析》第二周学习报告

    <Linux内核分析>第二周学习报告 ——操作系统是如何工作的 姓名:王玮怡  学号:20135116 第一节 函数调用堆栈 一.三个法宝 二.深入理解函数调用堆栈 三.参数传递与局部变量 ...

  2. LINUX内核分析第六周学习总结——进程的描述和进程的创建

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  3. LINUX内核分析第六周学习总结——进程的描述与创建

    LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...

  4. linux内核分析第六周学习笔记

    LINUX内核分析第六周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...

  5. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  6. linux内核分析 第六周

    一.进程的描述 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 1.进程控制块PCB--task_struct 进程状态 进程打开的文件 进程优先级信息 2. ...

  7. Linux内核分析第六周学习总结:进程的描述和进程的创建

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程的描述 ...

  8. 《Linux内核分析》第一周学习报告

    第一周:计算机是如何工作的 姓名:王玮怡  学号:20135116 第一节 存储程序计算机工作模型(冯诺依曼体系结构) IP指向的内存地址,取指令执行,完成后,IP值自加一,取下一条指令再执行. AP ...

  9. Linux内核分析——第六周学习笔记20135308

    第六周 进程的描述和进程的创建 一.进程描述符task_struct数据结构 1.操作系统三大功能 进程管理 内存管理 文件系统 2.进程控制块PCB——task_struct 也叫进程描述符,为了管 ...

随机推荐

  1. Linux 小知识翻译 - 「Shell 脚本」

    这次说说「Shell 脚本」. 根据上回的介绍,Shell就是「作为联系Linux和用户的接口而存在的软件」.在Linux环境中,通过Shell来操作系统很普遍. 这里,考虑到有时候可能想要「多次的进 ...

  2. VMware NAT 设置原理

    1.网络地址转换(NAT):默认使用VMnet8 (强烈推荐) 这种访问模式指的是虚拟机不占用主机所在局域网的ip,通过使用主机的NAT功能访问局域网和互联网,意味着虚拟机可以访问局域网中的其他电脑, ...

  3. CorelDRAW(cdr) 2018安装教程详解

    令人期待的coreldraw2018最新版已经发布了,相信各位设计从业者已经迫不及待想要知道这次版本会带来什么新的东西,本次小编带来的coreldraw2018破解版,附有注册补丁,激活之后可以永久免 ...

  4. 装饰器 以及 django 中的应用

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权 ...

  5. 用scrapy爬取亚马逊网站项目

    这次爬取亚马逊网站,用到了scrapy,代理池,和中间件: spiders里面: # -*- coding: utf-8 -*- import scrapy from scrapy.http.requ ...

  6. 20145236《网络攻防》 Exp3 免杀原理与实践

    20145236<网络攻防> Exp3 免杀原理与实践 一.基础问题回答 1.杀软是如何检测出恶意代码的? 恶意代码有其特有的特征码,杀软将特征码加入检测库中,当检测到一段代码中具有这样的 ...

  7. JS进阶之---this的指向

    this到底指向什么地方,决定于函数的调用方式. 1. 指向全局变量 --- 函数被单独调用的时候 function fn() { console.log( this.a ); } var a = 2 ...

  8. AI 判别式模型和生成式模型

    判别式模型(discriminative model) 生成式模型(generative model) 对于输入x,类别标签y:产生式模型估计它们的联合概率分布P(x,y)判别式模型估计条件概率分布P ...

  9. 如何在Skyline中加载ArcGISServer发布的WMS和WMTS服务

    如何在Skyline中加载ArcGISServer发布的WMS和WMTS服务? 我这里的测试环境是ArcGISServer10.1和TerraExplorer Pro7.0,主要过程截图如下,

  10. java算法----排序----(4)快速排序

    package log; public class Test4 { /** * java算法---快速排序 * * @param args */ public static void main(Str ...