linux中关于创建子进程系统堆栈的分析
2013-03-21 18:56
417 查看
linux中关于创建子进程系统堆栈的分析
linux中关于创建子进程系统堆栈的分析 | |
来源: ChinaUnix博客 日期: 2008.07.23 09:57 (共有条评论) 我要评论 | |
再次看到LINUX中的fork系统调用时,读到copy_thread(),2.4内核代码是这样的 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; struct_cpy(childregs, regs); childregs->eax = 0; childregs->esp = esp; p->thread.esp = (unsigned long) childregs; p->thread.esp0 = (unsigned long) (childregs+1); p->thread.eip = (unsigned long) ret_from_fork; savesegment(fs,p->thread.fs); savesegment(gs,p->thread.gs); unlazy_fpu(current); struct_cpy(&p->thread.i387, ¤t->thread.i387); return 0; } 这个函数就是复制父进程堆栈的内容到子进程的堆栈中去,并且设置一下子进程的task_struct内容,我们重点关心蓝色部分,也就是子进程系统堆栈的分析部分 特别是这句代码 ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; P是新建的进程的task_struct结构,他是在新分配的二个页面(THREAD_SIZE)的最低下,而pt_regs是系统的保存系统调用时或者中断时寄存器的数据结构,如果P+THREAD_SIZE就代表子进程的堆栈的最顶端也就是ESP,如果转换成pt_regs结构再减去1,这里的计算结果实在是太模糊,,如果按照pt_regs结构减掉1的话就是分配了一个pt_regs,那也就是说Linux内核情景分析书中302页的图 这个图的理解是从系统空间堆栈中减掉一个pt_regs结构,实际上变相分配堆栈给pt_regs了。这样的计算方法很多,但是我们再看一下2.6.24内核是如何清晰的描绘的 首先2.6.24内核在task_struct结构中增加了一个void类型的指针stack,使它指向进程的系统空间堆栈顶端这是在do_fork()-->copy_process()-->dup_task_struct()函数中实现的: struct thread_info *ti; ti = alloc_thread_info(tsk); if (!ti) { free_task_struct(tsk); return NULL; } *tsk = *orig; tsk->stack = ti; 这里通过下面函数 #define alloc_thread_info(tsk) ((struct thread_info *) \ __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE))) 这里很明显其实就是分配系统的堆栈,并把地址转换成thread_info结构指针 这样就得到了系统的堆栈指针,然后同样通过copy_thread()-->task_pt_regs() #define task_pt_regs(task) \ ({ \ struct pt_regs *__regs__; \ __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ __regs__ - 1; \ }) #define task_stack_page(task) ((task)->stack) #define KSTK_TOP(info) \ ({ \ unsigned long *__ptr = (unsigned long *)(info); \ (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ }) 好了我们再次看到上面的代码蓝色部分取出了刚才的系统堆栈指针,然后我们看到他有一个减8的计算,看一下这个图 为什么要减8呢,我们分析一下原来系统调用时或者中断时的情况,如果优先级别一样就不会把SS,ESP压入内核栈,这时候pt_regs结构体中的esp,xss不存在,为了防止非法访问,总在内核栈上空8个字节. |
相关文章推荐
- linux中关于创建子进程系统堆栈的分析
- 分析Linux内核创建一个新进程的过程
- 作业六:分析Linux内核创建一个新进程的过程
- linux中关于tmpfs文件系统资料的整理与分析
- Linux下进程创建Fork()函数分析
- Linux0.11 创建进程的过程分析--fork函数的使用
- 基于I386的Linux2.4.18进程创建的分析和实践
- linux系统编程之进程(八):守护进程详解及创建,daemon()使用
- Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程
- 基于visual c++之windows核心编程代码分析(57)监控系统的每一个进程的创建
- Linux下进程的创建过程分析(_do_fork/do_fork详解)--Linux进程的管理与调度
- 基于I386的Linux2.4.18进程创建的分析和实践
- “Linux内核分析”实验报告(六)分析Linux内核创建一个新进程的过程
- 实验六:分析Linux内核创建一个新进程的过程
- 分析Linux内核创建一个新进程的过程【转】
- Linux内核作业--分析Linux内核创建一个新进程的过程
- 分析Linux内核创建一个新进程的过程
- 基于Linux系统中进程调度分析
- Linux0.11 创建进程的过程分析--fork函数的使用
- shell监控linux系统进程创建脚本分享