gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 01:26:31 24 4
gpt4 key购买 nike

据我了解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 number 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//maps 时),因为包含该地址的 vma 保证包含(主)堆栈。

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

关于linux - 为什么 mm_struct->start_stack 和 vm_area_struct->start 不指向同一个地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27749792/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com