了解从进程内核堆栈中获取task_struct指针 [英] Understanding the getting of task_struct pointer from process kernel stack

查看:162
本文介绍了了解从进程内核堆栈中获取task_struct指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我正在阅读Robert Love的书"Linux Kernel Development 3d Edition".他在那里写了有关thread_info结构的信息,该结构包含指向task_struct结构的指针,并且据我所知,它位于进程的内核堆栈的底部或顶部(取决于体系结构).直到最近我才对Linux内核API感到陌生,并且不了解current()方法的存在.本书摘录了有关current()方法实际工作原理的摘录:

Right now I'm reading the book "Linux Kernel Development 3d Edition" by Robert Love. There he write about the thread_info struct which contains the pointer to task_struct struct and, as I understood, located at the bottom or at the top of kernel stack of process (depends on architecture). I wasn't familiar with Linux kernel API until recently and I wasn't known of current() method existence. There is an excerpt from the book related to how current() method actually works:

在x86上,通过屏蔽堆栈的13个最低有效位来计算电流 获取thread_info结构的指针. current_thread_info()函数.程序集如下所示: movl $ -8192,%eax andl%esp,%eax 假设堆栈大小为8KB,启用4KB堆栈时,将4096 代替8192.

On x86, current is calculated by masking out the 13 least-significant bits of the stack pointer to obtain the thread_info structure.This is done by the current_thread_info() function.The assembly is shown here: movl $-8192, %eax andl %esp, %eax This assumes that the stack size is 8KB.When 4KB stacks are enabled, 4096 is used in lieu of 8192.

我的问题是:

  1. 据我所知,如果我们将十进制值表示为一组位,那么该组中只有一个最低有效位,不是吗?
  2. 神奇的数字13是什么?

对于那些将阅读本主题的人来说,我所说的问题可能会导致结论,即作者对内存分配和管理过程的理解不正确.好的,由于我可以将分配给堆栈的内存表示为充满位(或字节)的功能区,因此这可能是正确的.所有这些字节都可以由表示为某个十进制值的特定内存地址访问.堆栈的原点是最低的内存地址,堆栈的fin是最高的内存地址值.但是,我们如何才能仅通过屏蔽位于ARBITRARY的堆栈指针的13个最低有效位来获得指向位于堆栈末尾的thread_info结构的指针(如果我理解正确,我们就屏蔽掉了堆栈指针ADDRESS表示为十进制值.

For thous who will read this topic, the questions I have voiced can lead to conclusion that the author don't understand properly the process of memory allocation and administration. Ok, that's may be right due to the fact that in my mind I can represent the memory allocated for the stack as the ribbon full of bits (or bytes). All of this bytes accessible by a specific memory address represented as some decimal value. The origin of the stack is the lowest memory address and the fin of the stack is the highest value of memory address. But HOW, HOW can we get the the pointer to the thread_info struct located at the, say, end of the stack only by masking out 13 least-significant bits of ARBITRARY located stack pointer (If I understood correctly, we masking out bits of the stack pointer ADDRESS represented as decimal value).

推荐答案

内核堆栈在顶部包含一个特殊的结构-

The kernel stack contains a special struct at the top -- thread_info:

 26 struct thread_info {
 27         struct task_struct      *task;          /* main task structure */
 28         struct exec_domain      *exec_domain;   /* execution domain */
 29         __u32                   flags;          /* low level flags */
 30         __u32                   status;         /* thread synchronous flags */
 31         __u32                   cpu;            /* current CPU */
 32         int                     preempt_count;  /* 0 => preemptable,
 33                                                    <0 => BUG */
 34         mm_segment_t            addr_limit;
 35         struct restart_block    restart_block;
 36         void __user             *sysenter_return;
 37 #ifdef CONFIG_X86_32
 38         unsigned long           previous_esp;   /* ESP of the previous stack in
 39                                                    case of nested (IRQ) stacks
 40                                                 */
 41         __u8                    supervisor_stack[0];
 42 #endif
 43         unsigned int            sig_on_uaccess_error:1;
 44         unsigned int            uaccess_err:1;  /* uaccess failed */
 45 };

因此,要获取task_struct,您需要使用

So, to get the task_struct you'll need to get a thread_info pointer with GET_THREAD_INFO from the ASM-code:

183 /* how to get the thread information struct from ASM */
184 #define GET_THREAD_INFO(reg)     \
185         movl $-THREAD_SIZE, reg; \
186         andl %esp, reg

...或使用 current_thread_info 来自C代码:

... or with current_thread_info from the C-code:

174 /* how to get the thread information struct from C */
175 static inline struct thread_info *current_thread_info(void)
176 {
177         return (struct thread_info *)
178                 (current_stack_pointer & ~(THREAD_SIZE - 1));
179 }

请注意,对于x86_32和x86_64,定义为(PAGE_SIZE << THREAD_SIZE_ORDER)THREAD_SIZE_ORDERTHREAD_SIZE等于1,因此THREAD_SIZE的结果为8192(2 ^ 13或1 << 13).

Note that THREAD_SIZE defined as (PAGE_SIZE << THREAD_SIZE_ORDER) and THREAD_SIZE_ORDER equals 1 for both x86_32 and x86_64 so THREAD_SIZE results to 8192 (2^13 or 1<<13).

这篇关于了解从进程内核堆栈中获取task_struct指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆