获取当前进程描述符地址 -- current

来源:互联网 发布:网络诈骗的存在危险性 编辑:程序博客网 时间:2024/04/29 21:34
在内核代码中当需要访问当前进程的task_struct结构时使用的指针current实际上是个宏定义,它是根据当前进程的堆栈指针ESP计算出来的。

#define current get_current()

static inline struct task_struct * get_current(void)
{
    
return current_thread_info()->task;
}

static inline struct thread_info *current_thread_info(void)
{
    
struct thread_info *ti;
    __asm__(
"andl %%esp,%0":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
    
return ti;
}

#define THREAD_SIZE     (8192)
注:
(1)THREAD_SIZE(8K)即thread_info结构体的大小
(2)"andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1))
将内核堆栈栈顶ESP指针和(~(THREAD_SIZE - 1)相与:获得的结果为内核堆栈最底端地址(也就是结构体thread_info的地址)
struct thread_info {
    
struct task_struct      *task;           
    
struct exec_domain      *exec_domain;  
    unsigned 
long           flags;           
    unsigned 
long           status;          
    __u32                   cpu;                 
    __s32                   preempt_count;
    mm_segment_t            addr_limit;    
    
struct restart_block    restart_block;
    unsigned 
long           previous_esp;  
    __u8                    supervisor_stack[
0];
}
;

struct task_struct {
    
volatile long      state; 
    
struct thread_info *thread_info;
    atomic_t           usage;
    unsigned           
long flags;


ESP、thread.info、task_struct、task_struct.thread的关系结构示意图

            |------------|<---0x015fbfff
            |  kernel |  |
            |  stack  |  |
            |         |  |
            |         |  |
            |        /|/ |        current--+--->|--------------|
            |            |                 |    |              |
            |            |<---%%esp        |    |--------------|
            |            |    (ESP)        |    | *thread_info |
            |            |                 |    |--------------|
            |            |                 |    |              |
            |            |                 |    |              |
 -----------|------------|<---0x015fa030   |    |              |
    /|/     |    *task   |-----------------+    |--------------|
     |      |------------|                      |              |
 thread_info|            |                      |    thread    |
     |      |            |                      |              |
    /|/     |            |                      |--------------|
 -----------|------------|<---0x15fa000         |              |
                                                |              |
                                                |--------------|
                                                  task_struct