如何区分内核空间中vm_area_struct的堆栈节点和堆节点?

时间:2016-12-09 04:22:17

标签: linux-kernel

在内核空间中使用伪驱动程序我试图实现一个进程的map文件,以便如何区分虚拟内存节点中的堆栈和堆节点。

long myIoctl(struct file* fp1, unsigned int pid, unsigned long b)
{
    struct module* mod = NULL;
    struct task_struct *my_task = NULL;
    struct vm_area_struct * vm_area = NULL;
    my_task = current;
    vm_area = my_task -> mm -> mmap;
    mod = THIS_MODULE;


    while (vm_area) {
        printk ("%p-%p  ", (int *)(vm_area -> vm_start), (int *) (vm_area -> vm_end));
        printk ("%d   ", vm_area -> vm_flags);
        if ((vm_area -> vm_flags) & VM_READ) {
            printk("r");
        }
        if ((vm_area -> vm_flags) & VM_WRITE) {
            printk("w");
        } else {
            printk ("_");
        }
        if ((vm_area -> vm_flags) & VM_EXEC) {
            printk("x");
        } else {
            printk ("_");
        }
        if ((vm_area -> vm_flags) & VM_SHARED) {
            printk("s");
        } else {
            printk ("p");
        }

        printk ("  %.8lx  ", (vm_area -> vm_pgoff) << 12 );
        if (vm_area -> vm_file) {
            printk ("%ld  ", vm_area -> vm_file -> f_inode -> i_ino);
            printk ("%u\n", MAJOR(vm_area -> vm_file -> f_inode -> i_rdev));
            printk (":%u\n", MINOR(vm_area -> vm_file -> f_inode -> i_rdev));
        } else {
            printk ("0\n");
        }
        vm_area = vm_area -> vm_next;

    }

    return 0;
}

in the image see stack and heap sections

1 个答案:

答案 0 :(得分:1)

操作系统已实现/ proc /&lt; pid&gt; / maps显示该进程的所有VMA,包括堆栈,堆,当然还有mmap-ed。

如果你想检查所有这些信息填写的位置,你可以检查内核源代码,相关代码(查找给定PID的VMA)似乎在这里: fs/proc/task_mmu.c

而且,确实,&#34; [堆]&#34;由上面的src文件(内核版本3.10.24)中的代码片段标记:

fs / proc / task_mmu.c:show_map_vma()

... 
if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) 
{ 
    name = "[heap]"; goto done; } 
... 

如果您想检查特定细分的起始地址,还有一件事,请检查 中是否定义 mm_struct 。你会得到以下的东西: -

struct mm_struct{
......
    unsigned long start_code, end_code, start_data, end_data;
    unsigned long start_brk, brk, start_stack;
......
}
  1. start_code,end_code代码段的开始和结束地址;
  2. start_data,end_data数据部分的起始和结束地址;
  3. start_brk,brk堆的起始和结束地址;
  4. start_stack可以预测,堆栈区域的开始;