linux – 为什么mm_struct-> start_stack和vm_area_struct-> start不指向同一个地址?

linux – 为什么mm_struct-> start_stack和vm_area_struct-> start不指向同一个地址?,第1张

概述据我了解 Linux内核中的内存管理,有一个mm_struct结构负责每个进程中的地址空间.一个重要的存储区域是堆栈.这应该由vm_area_struct内存区域标识,mm_struct本身有一个指针mm_struct-> stack_start,它是堆栈的地址. 我遇到了下面的代码,我无法理解的是为什么任何内存区域的起始/结束地址都不等于mm_struct-> stack_start值.任何帮助 据我了解 Linux内核中的内存管理,有一个mm_struct结构负责每个进程中的地址空间.一个重要的存储区域是堆栈.这应该由vm_area_struct内存区域标识,mm_struct本身有一个指针mm_struct-> stack_start,它是堆栈的地址.

我遇到了下面的代码,我无法理解的是为什么任何内存区域的起始/结束地址都不等于mm_struct-> stack_start值.任何帮助理解这一点将非常感激.谢谢

加载已编译内核模块的一些结果:

Vma number 14: Starts at 0x7fff4bb68000,Ends at 0x7fff4bb8a000
Vma number 15: Starts at 0x7fff4bbfc000,Ends at 0x7fff4bbfe000
Vma number 16: Starts at 0x7fff4bbfe000,Ends at 0x7fff4bc00000
Code Segment start = 0x400000,end = 0x400854
Data Segment start = 0x600858,end = 0x600a94
Stack Segment start = 0x7fff4bb88420

可以发现堆栈段启动(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%lx\n",vma->vm_start,vma->vm_end);        }        printk("\nCode  Segment start = 0x%lx,end = 0x%lx \n"                 "Data  Segment start = 0x%lx,end = 0x%lx\n"                 "Stack Segment start = 0x%lx\n",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 – 这样每个线程的堆栈可以独立增长.

总结

以上是内存溢出为你收集整理的linux – 为什么mm_struct-> start_stack和vm_area_struct-> start不指向同一个地址?全部内容,希望文章能够帮你解决linux – 为什么mm_struct-> start_stack和vm_area_struct-> start不指向同一个地址?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1017979.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存