Linux0.11任务0中fork和pause的内嵌问题

产生进程1的fork和pause为什么要用内联函数而不能使用函数掉用的原因,网上的很多回答都是创造一个干净的用户态堆栈,至于不干净的用户堆栈空间会带来什么影响,无人提及

在理解下面代码的前,我们需要理解一下fork函数的特殊性,

fork会“两次返回”,一次子进程返回0,一次父进程返回子进程的pid

fork返回可能执行子进程,也可能执行父进程,先后顺序不确定

复制代码
    /*    
     * fork程序是一个系统调用,使用_syscall0进程展开生成,0表示没有参数
     *
     * #define _syscall0(type,name) \
     *    type name(void) \
     *    { \
     *    long __res; \
     *    __asm__ volatile ("int $0x80" \
     *     : "=a" (__res) \
     *     : "0" (__NR_##name)); \
     *    if (__res >= 0) \
     *     return (type) __res; \
     *    errno = -__res; \
     *    return -1; \
     *
     * 根据前面的定义static inline _syscall0(int,fork) 展开
     *
     * int fork() {
     *    register eax __ret;
     *    eax= __NR_fork;
     *    int 0x80
     *    if (eax >= 0)
     *        return int __res;
     *    error = - __res
     *    return -1
     * }
     * INT 0x80是软中断函数,其调用流程为:
     * CPU通过中断向量0x80找到对应的描述符,此描述符包含了段选择子和偏移地址和其DPL
     * CPU检查当前的DPL是否小于描述符的DPL,如果小于拒绝执行
     * CPU会从当前TSS段中找到中断处理程序的栈选择子和栈指针作为新的栈地址(tss.ss0, tss.esp0)
     * 如果DPL发生变化则将当前的SS, ESP, EFLAGS, CS, EIP压入新的栈中
     * 如果DPL没有发生变化则将EFLAGS, CS, EIP压如新的栈中
     * CPU从中断描述符中取CS:EIP作为新的运行地址
     * 
     * 为什么fork和pause需要inline执行呢
     * 假设不是内联执行,当掉用fork时会ESP为A,将CS:IP压入当前系统堆栈中也就是任务0的用户堆栈中stack_start,此时ESP为B
     * 然后执行INT 80, 此指令会将SS ESP EFLAGS CS EIP ... 压入任务0的内核堆栈
     * 在系统掉用过程中会产生任务切换,因此从系统调用退出时就可能有两种情况,一种是task0,一种是task1
     * 怎么区分task0还是task1,INT 80返回后通过eax寄存器判断当前是task0还是task1
     * 如果是task1执行,fork退出时用户态ESP恢复返回到init()函数中则不会有影响
     * 如果是task0执行,fork退出时用户态ESP恢复返回到for(;;) pause执行,pause执行将CS:IP压入堆栈,
     *   和fork()系统掉用一样,pause从内核中返回时可能进入task1(fork)进程中
     *   fork函数使用RET返回,会使用堆栈中的CS:IP恢复执行
     * 我们设想一下fork退出时会使用CS:IP进行恢复(能恢复吗),此时CS:IP是task0(pause)压入堆栈的返回地址
     * 也就是说task1执行完毕后会进入到pause中执行,系统出现问题
     * 
     */
    if (!fork()) {        /* we count on this going ok */
        init();
    }
复制代码

写到这里应该理解了,其实可以深度思考一下,fork,pause只要两个其中一个为inline就可以了,通过代码实际测试可以验证我的想法

posted on   sudochen  阅读(451)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示