Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为什么mm_结构->;启动堆栈和虚拟机区域结构->;启动don';t指向同一个地址?_Linux_Linux Kernel_Kernel_Internals - Fatal编程技术网

Linux 为什么mm_结构->;启动堆栈和虚拟机区域结构->;启动don';t指向同一个地址?

Linux 为什么mm_结构->;启动堆栈和虚拟机区域结构->;启动don';t指向同一个地址?,linux,linux-kernel,kernel,internals,Linux,Linux Kernel,Kernel,Internals,据我所知,Linux内核中的内存管理有一个mm_结构,负责每个进程中的地址空间。一个重要的内存区域是堆栈。这应该由vm_区域结构内存区域标识,而mm_结构本身有一个指针mm_struct->stack_start,它是堆栈的地址 我无意中看到了下面的代码,但我无法理解的是,为什么任何内存区域的开始/结束地址都不等于mm_struct->stack_开始值。如果您能帮助理解这一点,我们将不胜感激。谢谢 加载已编译内核模块的一些结果: Vma编号14:从0x7FFF4B68000开始,到0x7FFF

据我所知,Linux内核中的内存管理有一个mm_结构,负责每个进程中的地址空间。一个重要的内存区域是堆栈。这应该由vm_区域结构内存区域标识,而mm_结构本身有一个指针mm_struct->stack_start,它是堆栈的地址

我无意中看到了下面的代码,但我无法理解的是,为什么任何内存区域的开始/结束地址都不等于mm_struct->stack_开始值。如果您能帮助理解这一点,我们将不胜感激。谢谢

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

Vma编号14:从0x7FFF4B68000开始,到0x7FFF4B8A000结束 Vma编号15:从0x7fff4bbfc000开始,到0x7fff4bbfe000结束 Vma编号16:从0x7FFF4BFE000开始,到0x7FFF4BC0000结束 代码段开始=0x400000,结束=0x400854 数据段开始=0x600858,结束=0x600a94 堆栈段开始=0x7FFF4B88420

可以发现堆栈段开始(0x7FFF4B88420)属于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");
#包括
#包括
#包括
#包括
#包括
静态int pid_mem=1;
静态无效打印\u mem(结构任务\u结构*任务)
{
结构mm_结构*mm;
结构vm_区域_结构*vma;
整数计数=0;
mm=任务->mm;
printk(“\n此mm_结构有%d个vma。\n”,mm->map_计数);
用于(vma=mm->mmap;vma;vma=vma->vm\U下一步){
printk(“\nVma编号%d:\n”++计数);
printk(“开始于0x%lx,结束于0x%lx\n”,
vma->vm_开始,vma->vm_结束);
}
printk(“\n代码段开始=0x%lx,结束=0x%lx\n”
数据段开始=0x%lx,结束=0x%lx\n
“堆栈段开始=0x%lx\n”,
mm->开始代码,mm->结束代码,
mm->开始数据,mm->结束数据,
mm->启动_堆栈);
}
静态整数mm\u exp\u负载(无效){
结构任务\u结构*任务;
printk(“\n将要查找的进程id设置为%d。\n”,pid\u mem);
对于每个流程(任务){
如果(任务->pid==pid\U内存){
printk(“%s[%d]\n”,任务->通信,任务->pid);
打印内存(任务);
}
}
返回0;
}
静态空隙mm\u exp\u卸载(空隙)
{
printk(“\n打印段信息模块退出。\n”);
}
模块初始化(毫米扩展负载);
模块退出(mm\u exp\u卸载);
模块参数(pid_mem,int,0);
模块作者(“Krishnakumar.R,rkrishnakumar@gmail.com");
模块描述(“打印段信息”);
模块许可证(“GPL”);

看起来start\u stack是初始堆栈指针地址。它由内核在程序执行时计算,并基于可执行文件中给定的堆栈节地址。我认为此后它根本不会更新。系统至少在一个实例中使用start_stack:标识哪个vma代表“堆栈”(在提供/proc//maps时),因为包含该地址的vma保证包含(主)堆栈


但请注意,这只是“主”(初始)线程的堆栈;多线程程序也会有其他堆栈——每个线程一个。因为它们都共享相同的地址空间,所以所有线程都将显示相同的vma集,我想您会发现它们都具有相同的start_堆栈值。但只有主线程的堆栈指针将位于主堆栈vma中。其他线程都有自己的堆栈VMA,这样每个线程的堆栈都可以独立增长。

一般来说,一个进程有一个mm_结构,但许多vm_区域结构都响应一个mmaped区域

例如,在32位系统中,进程的虚拟地址空间为4GB,所有地址空间都由mm_结构指向。但是,4GB空间中可能有许多区域。每个区域由一个vm\u area\u struct指向,该区域受vm\u area\u struct->start和vm\u area\u struct->end的限制。因此,mm_结构结构显然包含一个vm_区域结构的列表

是详细的介绍