• Linux内核分析作业六


    1.阅读理解task_struct数据结构

    2.分析fork函数对应的内核处理过程sys_clone,理解创建一个新进程如何创建和修改task_struct数据结构;

    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!
    ");
    } 
    else 
    {  
        /* parent process  */
        printf("This is Parent Process!
    ");
        /* parent will wait for the child to complete*/
        wait(NULL);
        printf("Child Complete!
    ");
    }
    }
    

    fork系统调用在父进程和子进程各返回一次。

    子 pid=0 
    父 pid=子进程的id
    

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

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

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

    • 复制一个PCB——task_struct

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

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

    • 从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy _thread in copy _process

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

    4.使用gdb跟踪创建新进程的过程(实验)

    准备工作:在MenuOS里添加fork命令
    (这一步跟上一次实验的做法相同)

    rm menu -rf 
    git clone https://github.com/mengning/menu.git   # 更新Menu
    cd menu
    mv test_fork.c test.c   # 把test.c覆盖掉
    make rootfs
    

    这块克隆有问题我用了字符界面才成功的,神奇吧,

    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
    

    呵呵呵呵,尝试过超级多次无法下载kernel

    设置断点

    b sys_clone 
    b do_fork
    b dup_task_struct
    b copy_process
    b copy_thread
    b ret_from_fork
    

    5.新进程是从哪里开始执行的?

    ret _ from _ fork

    总结

    大概的原理基本都懂了,更详细的总结请看http://www.cnblogs.com/javajy/p/5338786.html

  • 相关阅读:
    在Ubuntu上安装PHPStudy组件
    手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql
    ErrorKiller:Failed to decode response: zlib_decode(): data error
    HTTP和FTP上传文件的区别
    关于HTTP,你知道哪些?
    史上最全的FTP网址
    深入解读TCP/IP
    nefu 462 fib组合
    MZL's xor
    The Highest Mark(01背包)
  • 原文地址:https://www.cnblogs.com/javajy/p/5340329.html
Copyright © 2020-2023  润新知