linux – 为什么mm_struct-> start_stack和vm_area_struct-&am
据我了解
Linux内核中的内存管理,有一个mm_struct结构负责每个进程中的地址空间.一个重要的存储区域是堆栈.这应该由vm_area_struct内存区域标识,mm_struct本身有一个指针mm_struct-> stack_start,它是堆栈的地址.
我遇到了下面的代码,我无法理解的是为什么任何内存区域的起始/结束地址都不等于mm_struct-> stack_start值.任何帮助理解这一点将非常感激.谢谢 加载已编译内核模块的一些结果:
可以发现堆栈段启动(0x7fff4bb88420)属于vma号14但我不知道地址是不同的. 内核模块源代码: #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/mm.h> static int pid_mem = 1; static void print_mem(struct task_struct *task) { struct mm_struct *mm; struct vm_area_struct *vma; int count = 0; mm = task->mm; printk("nThis mm_struct has %d vmas.n",mm->map_count); for (vma = mm->mmap ; vma ; vma = vma->vm_next) { printk ("nVma number %d: n",++count); printk(" Starts at 0x%lx,Ends at 0x%lxn",vma->vm_start,vma->vm_end); } printk("nCode Segment start = 0x%lx,end = 0x%lx n" "Data Segment start = 0x%lx,end = 0x%lxn" "Stack Segment start = 0x%lxn",mm->start_code,mm->end_code,mm->start_data,mm->end_data,mm->start_stack); } static int mm_exp_load(void){ struct task_struct *task; printk("nGot the process id to look up as %d.n",pid_mem); for_each_process(task) { if ( task->pid == pid_mem) { printk("%s[%d]n",task->comm,task->pid); print_mem(task); } } return 0; } static void mm_exp_unload(void) { printk("nPrint segment information module exiting.n"); } module_init(mm_exp_load); module_exit(mm_exp_unload); module_param(pid_mem,int,0); MODULE_AUTHOR ("Krishnakumar. R,rkrishnakumar@gmail.com"); MODULE_DESCRIPTION ("Print segment information"); MODULE_LICENSE("GPL"); 解决方法
看起来start_stack是初始堆栈指针地址.它由程序执行时由内核计算,并基于可执行文件中给出的堆栈部分地址.我认为此后根本不会更新.系统在至少一个实例中使用start_stack:识别哪个vma表示“堆栈”(当提供/ proc //映射时),因为包含该地址的vma保证包含(主)堆栈.
但请注意,这只是“主”(初始)线程的堆栈;一个多线程程序也会有其他堆栈 – 每个线程一个.由于它们都共享相同的地址空间,因此所有线程都将显示相同的vmas集,我认为你会发现它们都具有相同的start_stack值.但只有主线程的堆栈指针才会在主堆栈vma中.其他线程将各自拥有自己的堆栈vmas – 这样每个线程的堆栈可以独立增长. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |