内存管理-31-每进程内存统计-5-/proc/pid/maps
一、简介
1. 打印内容
8295:/ # cat /proc/584/maps 62217e2000-62218e8000 r--p 00000000 fc:00 166440964 /system/bin/surfaceflinger 62218e8000-6221d75000 r-xp 00106000 fc:00 166440964 /system/bin/surfaceflinger 6221d75000-6221da4000 r--p 00593000 fc:00 166440964 /system/bin/surfaceflinger 6221da4000-6221dae000 rw-p 005c1000 fc:00 166440964 /system/bin/surfaceflinger 6221dae000-6221db0000 rw-p 00000000 00:00 0 [anon:.bss] 73bb942000-73bba02000 rw-s 00000000 00:0a 23087 /dmabuf: 73c9b80000-73c9f00000 rw-p 00000000 00:00 0 [anon:libc_malloc] 73cc064000-73cc067000 r--p 00000000 fc:01 15551301 /vendor/lib64/libvmmem.so 73cc067000-73cc06a000 r-xp 00003000 fc:01 15551301 /vendor/lib64/libvmmem.so 73cc06a000-73cc06b000 r--p 00006000 fc:01 15551301 /vendor/lib64/libvmmem.so 73ce892000-73ce894000 rw-p 00000000 00:00 0 745740f000-7457417000 rw-p 00000000 00:00 0 [anon:thread signal stack] 7458396000-74583b6000 r--s 00000000 00:14 17021 /dev/__properties__/u:object_r:system_prop:s0 7459c83000-7459c84000 r--p 00000000 00:00 0 [vvar] 7459c84000-7459c85000 r-xp 00000000 00:00 0 [vdso] //匿名页且vma->mm=NULL ... 7fd688f000-7fd68b0000 rw-p 00000000 00:00 0 [stack] //vma地址落在栈区间内,通常位于最后
每行对应一个 vm_area_struct 结构的打印,打印内容:
(1) 对于文件映射VMA
62218e8000-6221d75000: vma->vm_start - vma->vm_end r-xp: vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_MAYSHARE)? 'r''w''x''s' : '-''-''-''p'; 00106000: vma->vm_pgoff << PAGE_SHIFT; fc:00: MAJOR(inode->i_sb->s_dev):MINOR(inode->i_sb->s_dev); 166440964: inode->i_ino
(2) 对于匿名VMA
6221dae000-6221db0000: vma->vm_start - vma->vm_end rw-p: vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_MAYSHARE)? 'r''w''x''s' : '-''-''-''p'; 00000000: 固定为0 00:00: 固定为0:0 0: 固定为0
二、代码实现
1. 代码路径
static const struct pid_entry tgid_base_stuff[] = { //fs/proc/base.c REG("maps", S_IRUGO, proc_pid_maps_operations), }; static const struct pid_entry tid_base_stuff[] = { //fs/proc/base.c REG("maps", S_IRUGO, proc_pid_maps_operations), } proc_pid_maps_operations.pid_maps_open //base.c proc_pid_maps_op.show_map //task_mmu.c show_map_vma //task_mmu.c m_cache_vma //task_mmu.c 与打印无关
2. 打印函数
static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) //task_mmu.c { struct mm_struct *mm = vma->vm_mm; struct file *file = vma->vm_file; vm_flags_t flags = vma->vm_flags; unsigned long ino = 0; unsigned long long pgoff = 0; unsigned long start, end; dev_t dev = 0; const char *name = NULL; /* 若是文件映射对应的vma */ if (file) { struct inode *inode = file_inode(vma->vm_file); //return f->f_inode; dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; } start = vma->vm_start; end = vma->vm_end; /* * show_map_vma: (m, vma->vm_start, vma->vm_end, vma->vm_flags, vma->vm_pgoff) * 文件映射: pgoff=vma->vm_pgoff, dev=inode->i_sb->s_dev; ino = inode->i_ino; * 匿名映射 pgoff=0; dev=0; ino=0 * * 此函数打印如 “59e95d6000-59e961b000 r-xp 0002b000 fc:00 166573033” */ show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino); /* * Print the dentry name for named mappings, and a * special [heap] marker for the heap: */ /* 对于文件映射,打印pathname, 如"/system/bin/toybox", 然后就goto退出了 */ if (file) { seq_pad(m, ' '); seq_file_path(m, file, "\n"); goto done; } /* 尝试通过vm_ops->name回调获取匿名映射VMA对应的名字 */ if (vma->vm_ops && vma->vm_ops->name) { name = vma->vm_ops->name(vma); if (name) goto done; } /* _weak的,没定义,默认返回NULL */ name = arch_vma_name(vma); if (!name) { /* 匿名VMA的vma->mm=NULL打印这个 */ if (!mm) { name = "[vdso]"; goto done; } /* * 若VMA地址与堆空间[start_brk, brk]相交,就认为是heap * 实测 cat maps | grep heap 基本上是没有的,brk的确被舍弃了 */ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { name = "[heap]"; goto done; } /* vma->vm_start <= mm->start_stack && vma->vm_end >= mm->start_stack 栈向下增长的 */ if (is_stack(vma)) { name = "[stack]"; goto done; } /* 若是文件映射直接返回NULL,若是匿名映射的VMA返回 vma->anon_name */ if (vma_get_anon_name(vma)) { seq_pad(m, ' '); seq_print_vma_name(m, vma); } } done: if (name) { seq_pad(m, ' '); seq_puts(m, name); } seq_putc(m, '\n'); } static void show_vma_header_prefix(struct seq_file *m, unsigned long start, unsigned long end, vm_flags_t flags, unsigned long long pgoff, dev_t dev, unsigned long ino) { seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); seq_put_hex_ll(m, NULL, start, 8); seq_put_hex_ll(m, "-", end, 8); seq_putc(m, ' '); seq_putc(m, flags & VM_READ ? 'r' : '-'); seq_putc(m, flags & VM_WRITE ? 'w' : '-'); seq_putc(m, flags & VM_EXEC ? 'x' : '-'); seq_putc(m, flags & VM_MAYSHARE ? 's' : 'p'); seq_put_hex_ll(m, " ", pgoff, 8); seq_put_hex_ll(m, " ", MAJOR(dev), 2); seq_put_hex_ll(m, ":", MINOR(dev), 2); seq_put_decimal_ull(m, " ", ino); seq_putc(m, ' '); }
posted on 2026-04-21 21:29 Hello-World3 阅读(1) 评论(0) 收藏 举报
浙公网安备 33010602011771号