文章标题

本文深入探讨Linux内核中创建新进程的具体流程,重点分析fork函数对应的内核处理过程sys_clone,通过gdb跟踪调试,揭示进程创建背后的机制。

分析Linux内核创建一个新进程的过程

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

一、实验要求

  1. 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235
    分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构;
  2. 使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证您对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环境下完成实验。
  3. 特别关注新进程是从哪里开始执行的?为什么从哪里能顺利执行下去?即执行起点与内核堆栈如何保证一致。
  4. 根据本周所学知识分析fork函数对应的系统调用处理过程,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

二、实验步骤及现象

  1. 打开实验楼虚拟机实验环境,进入LinuxKernel文件夹,打开menu,修改其中test.c文件。
    这里写图片描述

需要修改的代码如下所示(即加入fork的系统调用函数,并修改主函数):
这里写图片描述

  1. 启动内核,检测fork()系统调用成果
    这里写图片描述
    现象:
    这里写图片描述

  2. 输入以下代码用gdb进行跟踪调试系统调用过程

Qemu –kernel linux-3.18.6/arch/x86/boot/bzImage –initrd rootfs.img –s –S
gdb  file ../linux-3.18.6/vmlinux
Target remote:1234

这里写图片描述

接下来,可以使用

b sys_clone
b do_fork
b dup_task_struct
b copy_process

等语句进行程序运行的断点设置,并使用 “n”逐条运行,使用“c”持续运行直至下一个断点。以下是几个断点及逐条执行跟踪的举例:
这里写图片描述
这里写图片描述
这里写图片描述
由此可见,fork()函数在这三个地方均已系统调用的方式访问了内核,总体上来说,fork()函数系统调用过程还是一个相对比较复杂的过程,通过单步调试和设置断点的方式很难一一追踪到,了解其奥妙。而且在设置断点过程中,追踪到 jmp_system_exit之后就追踪不到了

三、实验分析

进程的创建相关(有关内容参考网络):

  1. Linux中创建进程一共三个函数:
    (1)fork:创建子进程
    (2)vfork:与fork类似,但是父子进程共享地址空间,而且子进程先于父进程运行
    (3)clone:主要用于创建线程
    注:Linux线程是通过模拟进程实现的,
  2. 通过跟踪实验发现,以上fork、vfork、clone均是通过do_fork函数实现的:
    (1)调用copy_process,当前进程复制一份出来为子进程,并且为子进程设置相应的上下文信息
    (2)初始化vfork 完成处理信息
    (3)调用wake_up_new_task,将子进程放入调度器的队列中,此时的子进程就可以被调度进程选中,得以运行
    (4)如果是vfork调用,需要阻塞父进程,直到子进程执行exec
    注:如果没有vfork,进程的创建过程基本都在copy_process中
  3. 通过跟踪以及查阅相关资料可知,Linux中所有的进程都是基于复制的方式,然后对子进程做一些特殊的处理。线程又是一种特殊的进程。
  4. fork()函数创建一个新锦成是通过以下一系列函数实现的
    fork() ->system_clone(0 -> do_fork(0 -> dup_task_struct() -> copy_process() -> copy_thread() -> ret_from_fork

关于init进程创建(通过课程所得)

道生一: start_kernel -> cpu_idle
一生二: kernel_init kthread
二生三:0、1、2 号进程
三生万物:1号进程是所有用户态进程的祖先;2号进程是所有内核线程的祖先;而0号进程是所有进程的祖先

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值