Linux内核分析-分析Linux内核创建一个新进程的过程
作者:江军
ID:fuchen1994
实验题目:分析Linux内核创建一个新进程的过程
阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235;
分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构;
使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证您对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环境下完成实验。
特别关注新进程是从哪里开始执行的?为什么从哪里能顺利执行下去?即执行起点与内核堆栈如何保证一致
实验过程:
1.task_struct数据结构
struct task_struct {
volatile long state;进程状态
void *stack; 堆栈
pid_t pid; 进程标识符
unsigned int rt_priority;实时优先级
unsigned int policy;调度策略
struct files_struct *files;系统打开文件
...
}
2.fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构
return do_fork(clone_flags, newsp, , parent_tidptr, child_tidptr);
都是通过do_fork()实现进程的创建
linux系统是通过复制父进程的信息来创建子进程,在do_fork函数中,真正实现复制的是copy_process函数:
p = copy_process(clone_flags, stack_start, stack_size,child_tidptr, NULL, trace);
p = dup_task_struct(current);创建内核栈
retval = security_task_create(clone_flags);
retval = sched_fork(clone_flags, p);和调度相关的设置,cpu将调度这个task
retval = copy_thread(clone_flags, stack_start, stack_size, p); 复制父进程堆栈的内容到子进程的堆栈中去.这其中,copy_thread函数中的语句p->thread.ip = (unsigned long) ret_from_fork决定了新进程的第一条指令地址.
创建栈函数dup_task_struct:
tsk = alloc_task_struct_node(node);开辟内存空间
ti = alloc_thread_info_node(tsk, node);ti指向thread_info的首地址,同时也是系统为新进程分配的两个连续页面的首地址。
err = arch_dup_task_struct(tsk, orig);复制父进程的task_struct信息到新的task_struct里
tsk->stack = ti;task对应栈
setup_thread_stack(tsk, orig);初始化thread info结构
set_task_stack_end_magic(tsk);栈结束的地址设置数据为栈结束标示
3. 使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone

启动menu

调试

启动gdb

设置断点






操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!此时程序寄存器pc,在父、子进程的上下文中都声称,这个进程目前执行到fork调用即将返回(此时子进程不占有CPU,子进程的pc不是真正保存在寄存器中,而是作为进程上下文保存在进程表中的对应表项内)。问题是怎么返回,在父子进程中就分道扬镳。
父进程继续执行,操作系统对fork的实现,使这个调用在父进程中返回刚刚创建的子进程的pid(一个正整数)
子进程在之后的某个时候得到调度,它的上下文被换入,占据 CPU,操作系统对fork的实现,使得子进程中fork调用返回0。所以在这个进程(注意这不是父进程了哦,虽然是同一个程序,但是这是同一个程序的另外一次执行,在操作系统中这次执行是由另外一个进程表示的,从执行的角度说和父进程相互独立)中pid=0。这个进程继续执行的过程中,if语句中 pid<0不满足,但是pid==0是true。
4.新进程是从哪里开始执行的?为什么从哪里能顺利执行下去?即执行起点与内核堆栈如何保证一致
新进程是从ret_from_fork开始执行
为什么从哪里能顺利执行下去?
1. 在ret_from_fork之前,也就是在copy_thread()函数中*childregs = *current_pt_regs();该句将父进程的regs参数赋值到子进程的内核堆栈,
2. *childregs的类型为pt_regs,里面存放了SAVE ALL中压入栈的参数
3. 故在之后的RESTORE ALL中能顺利执行下去.
Linux内核分析-分析Linux内核创建一个新进程的过程的更多相关文章
- linux内核分析作业6:分析Linux内核创建一个新进程的过程
task_struct结构: struct task_struct { volatile long state;进程状态 void *stack; 堆栈 pid_t pid; 进程标识符 u ...
- 第六周分析Linux内核创建一个新进程的过程
潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: ...
- 实验 六:分析linux内核创建一个新进程的过程
实验六:分析Linux内核创建一个新进程的过程 作者:王朝宪 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029 ...
- 20135202闫佳歆--week6 分析Linux内核创建一个新进程的过程——实验及总结
week 6 实验:分析Linux内核创建一个新进程的过程 1.使用gdb跟踪创建新进程的过程 准备工作: rm menu -rf git clone https://github.com/mengn ...
- 《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁
20135311傅冬菁 分析Linux内核创建一个新进程的过程 一.学习内容 进程控制块——PCB task_struct数据结构 PCB task_struct中包含: 进程状态.进程打开的文件. ...
- 作业六:分析Linux内核创建一个新进程的过程
分析Linux内核创建一个新进程的过程 进程描述符PCB----task_struct数据结构 操作系统:1.进程管理 2.内存管理 3 文件系统 一.新进程如何创建和修改task_struct数据结 ...
- Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程
Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
- 第六周——分析Linux内核创建一个新进程的过程
"万子恵 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 &q ...
- 分析Linux内核创建一个新进程的过程
一.原理分析 1.进程的描述 进程控制块PCB——task_struct,为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct ...
随机推荐
- 客户端向服务端请求连接是出现"ssh : Connection refused"原因有哪些
注意:服务端的sshd服务已经正常开启 (可以正常进行连接) 1.在服务端负载比较高的情况下客户端请求连接时会出现连接被拒绝的情况
- rvm 安装ruby环境报错curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
很可能是rvm仓库版本过低,运行以下命令: rvm get head
- [BZOJ1196][HNOI2006]公路修建问题 二分答案+最小生成树
Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那 里的交通情况还是很糟糕.所以,OIER Association组 ...
- Ubuntu 14.04下 Java通用安装方法
参考: 解决Floodlight1.2+Mininet问题及使用安装 Ubuntu下安装JDK1.7图文详解 Ubuntu 14.04下 Java通用安装方法 1.到oracle官网下下载对应jdk包 ...
- React Native的SliderIOS滑块组件
import React,{Component}from 'react'; import { AppRegistry, StyleSheet, Text, View, SliderIOS, } fro ...
- AtCoder Grand Contest 013 C :Ants on a Circle
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- hdu 1427 速算24点 dfs暴力搜索
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem De ...
- 使用docker安装myql/redis等软件
使用docker安装myql/redis等软件 概述 基本命令 安装mysql 安装redis 概述 在开发时经常需要安装各种软件,有时甚至为了验证一个命令不得不安装配置一个缓存.数据库.MQ等,耽误 ...
- python获取文件扩展名的方法
主要介绍了python获取文件扩展名的方法,涉及Python针对文件路径的相关操作技巧 import os.path def file_extension(path): ] print file_ex ...
- DB中字段为null,为空,为空字符串,为空格要怎么过滤取出有效值
比如要求取出微信绑定的,没有解绑的 未绑定,指定字段为null 绑定的,指定字段为某个字符串 解绑的,有的客户用的是更新指定字段为1,有的客户更新指定字段为‘1’ 脏数据的存在,比如该字段为空字符 ...