本文转自:http://edsionte.com/techblog/archives/1953
本文将通过一些简单的内核模块程序,显示一个进程的所有内存区域。通过此程序理解进程的整个地址空间与内存区域之间的关系。
打印内存区域
上文中,我们通过打印某个进程的maps文件来查看某个进程的内存区域。如果你理解了进程,进程的用户空间,内存区域三者之间的关系,那么就可以通过内核模块的方式打印指定进程的内存区域。
通过在内核模块加载函数中调用下述函数,来打印当前进程的内存区域。首先通过全局变量current获得当前进程的mm字段,该字段指向当前进程的用户空间(mm_struct);由于多个内存区域(vm_area_struct)是通过一个双链表(最新内核中)链接在一起的,所以在接下来的for循环当中,依次遍历各个内存区域,打印当前内存区域的起始地址和终止地址,并且打印内核对该区域的操作权限。完整代码在这里。
static void list_myvma(void)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
printk("list vma..\n");
//print the current process's name and pid
printk("current:%s pid:%d\n",current->comm,current->pid);
down_read(&mm->mmap_sem);
//vma is a linklist
for(vma = mm->mmap; vma; vma = vma->vm_next)
{
//from the begining to the ending of a virtual memory area
printk("0x%lx-0x%lx ",vma->vm_start,vma->vm_end);
//check the flags of this VMA
if(vma->vm_flags & VM_READ)
printk("r");
else
printk("-");
if(vma->vm_flags & VM_WRITE)
printk("w");
else
printk("-");
if(vma->vm_flags & VM_EXEC)
printk("x");
else
printk("-");
if(vma->vm_flags & VM_SHARED)
printk("s");
else
printk("p");
printk("\n");
}
up_read(&mm->mmap_sem);
}
试一下吧!
应用层打印:
lenky@lenky-local:~$ cat /proc/self/maps
00400000-0040b000 r-xp 00000000 08:0b 919320 /bin/cat
0060a000-0060b000 r–p 0000a000 08:0b 919320 /bin/cat
0060b000-0060c000 rw-p 0000b000 08:0b 919320 /bin/cat
01dba000-01ddb000 rw-p 00000000 00:00 0 [heap]
7f3dd3b4f000-7f3dd4230000 r–p 00000000 08:0b 1582660 /usr/lib/locale/locale-archive
7f3dd4230000-7f3dd43ef000 r-xp 00000000 08:0b 529387 /lib/x86_64-linux-gnu/libc-2.17.so
7f3dd43ef000-7f3dd45ee000 —p 001bf000 08:0b 529387 /lib/x86_64-linux-gnu/libc-2.17.so
7f3dd45ee000-7f3dd45f2000 r–p 001be000 08:0b 529387 /lib/x86_64-linux-gnu/libc-2.17.so
7f3dd45f2000-7f3dd45f4000 rw-p 001c2000 08:0b 529387 /lib/x86_64-linux-gnu/libc-2.17.so
7f3dd45f4000-7f3dd45f9000 rw-p 00000000 00:00 0
7f3dd45f9000-7f3dd461c000 r-xp 00000000 08:0b 529041 /lib/x86_64-linux-gnu/ld-2.17.so
7f3dd47fb000-7f3dd47fe000 rw-p 00000000 00:00 0
7f3dd4819000-7f3dd481b000 rw-p 00000000 00:00 0
7f3dd481b000-7f3dd481c000 r–p 00022000 08:0b 529041 /lib/x86_64-linux-gnu/ld-2.17.so
7f3dd481c000-7f3dd481e000 rw-p 00023000 08:0b 529041 /lib/x86_64-linux-gnu/ld-2.17.so
7fffb693e000-7fffb695f000 rw-p 00000000 00:00 0 [stack]
7fffb69fe000-7fffb6a00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
lenky@lenky-local:~$