进程内核栈

来源:互联网 发布:淘宝热线电话 编辑:程序博客网 时间:2024/06/16 17:08

进程内核栈


为什么有进程内核栈

  进程在创建的时候也可以理解为一个程序,或者在简单的理解也可以把进程理解为一个函数,只不过这个函数很大而已,这个进程也需要有一些函数调用,也需要有一些函数去标记一些信息,于是 便有了进程内核栈这个东西。

  简单理解,进程内核栈实际上就是为进程开辟一个栈帧空间。
  但是这个栈帧空间不是用户的栈帧空间,因为用户的栈帧空间时不安全的,所以内核会专门为它开辟一个空间,这个就是内核栈。

进程内核栈和进程描述符的关系

  • 进程描述符

  进程描述符就是进程结构体(struct task_struct),每一个进程在创建之后都会有一个进程结构体,用来记录进程的所有信息。这其中的有一个信息就是就是进程内核栈,用一个指针指示。void *stack;就是指向下面的内核栈结构体的“栈底”。

  • 内核栈结构体

    union thread_union {        struct thread_info thread_info;        unsigned long stack[THREAD_SIZE/sizeof(long)];    };

其中的stack成员就是内核栈。

而其中的struct thread_info是记录部分进程信息的结构体,其中包括了进程上下文信息。

从这里可以看出内核栈空间和 thread_info是共用一块空间的。如果内核栈溢出, thread_info就会被摧毁,系统崩溃了~~~

让我们详细的看一下内核栈结构体。

    /*     * low level task data that entry.S needs immediate access to.     * __switch_to() assumes cpu_context follows immediately after cpu_domain.     */    struct thread_info {        unsigned long        flags;        /* low level flags */        int            preempt_count;    /* 0 => preemptable, <0 => bug */        mm_segment_t        addr_limit;    /* address limit */        struct task_struct    *task;        /* main task structure */        struct exec_domain    *exec_domain;    /* execution domain */        __u32            cpu;        /* cpu */        __u32            cpu_domain;    /* cpu domain */        struct cpu_context_save    cpu_context;    /* cpu context */        __u32            syscall;    /* syscall number */        __u8            used_cp[16];    /* thread used copro */        unsigned long        tp_value;        struct crunch_state    crunchstate;        union fp_state        fpstate __attribute__((aligned(8)));        union vfp_state        vfpstate;    #ifdef CONFIG_ARM_THUMBEE        unsigned long        thumbee_state;    /* ThumbEE Handler Base register */    #endif        struct restart_block    restart_block;    };

关键是其中的task成员,指向的是所创建的进程的struct task_struct结构体。就是进程描述符。

图文表示三者关系

内核栈—内核栈结构体(struct thread_info)—-进程描述符(struct task_struct)三者的关系入下图

这里写图片描述

内核栈的产生

在进程被创建的时候,fork族的系统调用中会分别为内核栈和struct task_struct分配空间,调用过程是:
fork族的系统调用—>do_fork—>copy_process—>dup_task_struct

0 0
原创粉丝点击