pmap,linux工具pmap原理?
pmap
显示进程的内存映像
语法格式
pmap [-x|-d] [-q] pids
pmap -V
命令简介
pmap命令主要用于显示指定进程的内存映像(或称地址空间)。其中,pids是一个或一组进程的PID。
除了指定进程,如果不加任何选项,pmap命令将会显示指定进程每个内存映像的起始地址、虚拟内存的大小、进程访问地址空间的权限,以及内存映射文件等。
命令选项
-x 增加一个标题行,同时显示每个内存映像实际使用的物理内存大小,以及内容已修改但尚未写到磁盘的页面数量等附加进程信息。
-d 增加一个标题行,同时显示内存映射文件的偏移值,以及存储设备的主次设备号等附加进程信息。
-q 采用安静方式,禁止显示汇总信息行。
-V 显示命令的版本信息,然后退出。
命令输出
Address: 内存映像的起始地址。
Kbytes: 内存映像的虚拟内存空间大小(单位为KB)。
RSS: 内存映像实际驻留物理内存的空间大小(单位为KB)。
Dirty: 内容已修改但尚未写到磁盘的页面空间大小(单位为KB),包括共享与专用的页面。
Mode: 访问内存映像的权限:r(读)、w(写)、x(执行)、s(共享)与p(专用)。
Mapping: 内存映射文件、分配的内存(其标志为“[ anon ]”)或程序栈(其标志为“[ stack ]”)。
Offset: 内存映射文件的偏移值。
Device: 存储设备的主次设备号。
应用实例
1. 显示bash的地址空间,查询每个内存映像的概况。
$ pmap 2775
2. 显示bash的地址空间,了解更多的信息。
linux工具pmap原理?
1. 概述
DMA(Direct Memory Access):直接存储器访问;
先看问题的引入:
- Non-DMA:CPU直接与设备进行数据交互,CPU的负载会随着数据的读写而增加;
- DMA:CPU不参与数据的直接传输,DMA Controller负责Device与Memory之间的数据搬运,并以中断信号的形式通知CPU;
- 可以看出,使用DMA的最大优点是可以提高CPU的使用率;
2. address mapping
DMA涉及三种地址空间:
- CPU虚拟地址:CPU使用的地址空间;
- CPU物理地址:CPU使用的虚拟地址通过MMU转换成物理地址;
- 总线地址:设备使用的地址空间;
CPU与Device看待地址的空间不一样,看几个示例:
- A:Host bridge负责将Bus address映射到CPU的物理地址空间,可以通过
ioremap
来使用,比如PCI/PCIe; - B:设备使用的总线地址,可以通过IOMMU访问到CPU的物理地址空间,由IOMMU来负责映射;
- C:设备使用的总线地址与CPU的物理地址相同,不需要使用IOMMU进行地址转换;
2.1 cache coherence
DMA的操作,通常与cache相关,先了解一下cache coherence:
- cache coherence设备:设备之间的读写不需要关心cache的一致性问题,硬件将确保数据一致,比如连接在ARM CCI端口上的设备就是cache coherence设备;
- non-coherence设备:需要额外的软件操作(flush/invalidate)等操作来确保数据一致;
3. DMA mappings
Linux内核中提供了两种dma mapping的接口:Consistent mapping和Stream mapping。
3.1 Consistent DMA mappings
- consistent mapping:对应于cache-coherence设备,硬件确保device和CPU都能并行访问数据,并能看到彼此的更新,而不需要软件的flush操作;
- 通常在驱动init时进行map操作,而在deinit时进行unmap操作;
通常在使用consistent dma mapping时,首先需要通过dma_alloc_coherent
接口来分配一段区域:
dma_alloc_coherent
用于分配coherent内存,并返回对应的虚拟地址;- 进行内存分配时,存在三种方式:1)优先从设备专用的dma池开始分配;2)无专用dma池,如果是dma-direct访问,通过dma_direct_alloc分配,而底层是依赖于CMA来分配;3)使用IOMMU的设备,则通过iommu的操作函数集来分配;
3.1 device reserved
通常,可以为设备指定专用的dma coherent的区域,有以下的方式:
- 通过在设备树中添加对应的属性值,驱动中可以调用
of_reserved_mem_device_init
最终完成dma区域的注册; - 直接通过接口
dma_decleare_coherent_memory
调用来进行注册;
3.2 dma pool
驱动中经常面临buffer的管理,可以使用dma pool机制来处理,大概的原理如下:
- dma-pool以页为单位来进行管理分配,可以通过添加多个dma池来使用;
- dma-pool子系统的细节描述,需要另起一篇文章了;
3.2 Streaming DMA mappings
- streaming mapping:对应于non-coherence设备;
- 通常在单次DMA传输时进行map,在传输完成后进行unmap(除非调用了
dma_sync_XXX()
函数); - non-coherence设备,由于buffer不与其他数据共享cache line,通常会work better;
先看一下数据一致性问题:
- dma to device时,需要将cache中的数据flush到memory中;
- dma from device时,需要先将cache中的数据invalidate掉,避免CPU读取的是原来的数据;
dma_map_single
函数如下:
- map操作时存在两种方式,直接映射或使用iommu来完成映射;
dma_unmap_single
是逆操作:
从上述函数中可以看到,最终都会调用到arch相关的cache操作,这个与体系结构是强相关的,以arm64为例:
- 最终的代码将调用到汇编中,操作也较简单,不再赘述了;
Linux kernel 已经通过 /proc/$PID/maps 和 smaps 将进程 PID 的内存信息暴露出来了,pmap 只要读取和解析这些文件就可以了。具体你可以直接看 pmap 的源码:
pmap.c · master · procps-ng / procps · GitLab
pmap命令详解
简介:
pmap - report memory map of a process(查看进程的内存映像信息)pmap命令用于报告进程的内存映射关系,是Linux调试及运维一个很好的工具。
用法
pmap [ -x | -d ] [ -q ] pids…
pmap -V
选项含义
-x extended Show the extended format. 显示扩展格式
-XX show everything the kernel provides 显示内核提供的一切信息
-d device Show the device format. 显示设备格式
-q quiet Do not display some header/footer lines. 不显示头尾行
-V show version Displays version of program. 显示版本
扩展格式和设备格式域:
Address: start address of map 映像起始地址
Kbytes: size of map in kilobytes 映像大小
RSS: resident set size in kilobytes 驻留集大小
Dirty: dirty pages (both shared and private) in kilobytes 脏页大小
Mode: permissions on map 映像权限: r=read, w=write, x=execute, s=shared, p=private (copy on write)
Mapping: file backing the map , or ‘[ anon ]’ for allocated memory, or ‘[ stack ]’ for the program stack. 映像支持文件,[anon]为已分配内存 [stack]为程序堆栈
Offset: offset into the file 文件偏移
Device: device name (major:minor) 设备名
- 查看进程1 的地址
[root@master ~]# pmap -d 1
1: /usr/lib/systemd/systemd --switched-root --system --deserialize 22
Address Kbytes Mode Offset Device Mapping
00007fd5d7abc000 16 r-x-- 0000000000000000 0fd:00000 libuuid.so.1.3.0
00007fd5d7ac0000 2044 ----- 0000000000004000 0fd:00000 libuuid.so.1.3.0
00007fd5d7cbf000 4 r---- 0000000000003000 0fd:00000 libuuid.so.1.3.0
00007fd5d7cc0000 4 rw--- 0000000000004000 0fd:00000 libuuid.so.1.3.0
00007fd5d7cc1000 224 r-x-- 0000000000000000 0fd:00000 libblkid.so.1.1.0
00007fd5d7cf9000 2048 ----- 0000000000038000 0fd:00000 libblkid.so.1.1.0
00007fd5d7ef9000 12 r---- 0000000000038000 0fd:00000 libblkid.so.1.1.0
00007fd5d7efc000 4 rw--- 000000000003b000 0fd:00000 libblkid.so.1.1.0
00007fd5d7efd000 4 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5d7efe000 84 r-x-- 0000000000000000 0fd:00000 libz.so.1.2.7
00007fd5d7f13000 2044 ----- 0000000000015000 0fd:00000 libz.so.1.2.7
00007fd5d8112000 4 r---- 0000000000014000 0fd:00000 libz.so.1.2.7
00007fd5d8113000 4 rw--- 0000000000015000 0fd:00000 libz.so.1.2.7
00007fd5d8114000 144 r-x-- 0000000000000000 0fd:00000 liblzma.so.5.0.99
00007fd5d8138000 2044 ----- 0000000000024000 0fd:00000 liblzma.so.5.0.99
00007fd5d8337000 4 r---- 0000000000023000 0fd:00000 liblzma.so.5.0.99
00007fd5d8338000 4 rw--- 0000000000024000 0fd:00000 liblzma.so.5.0.99
00007fd5d8339000 16 r-x-- 0000000000000000 0fd:00000 libcap-ng.so.0.0.0
00007fd5d833d000 2048 ----- 0000000000004000 0fd:00000 libcap-ng.so.0.0.0
00007fd5d853d000 4 r---- 0000000000004000 0fd:00000 libcap-ng.so.0.0.0
00007fd5d853e000 4 rw--- 0000000000005000 0fd:00000 libcap-ng.so.0.0.0
00007fd5d853f000 16 r-x-- 0000000000000000 0fd:00000 libattr.so.1.1.0
00007fd5d8543000 2044 ----- 0000000000004000 0fd:00000 libattr.so.1.1.0
00007fd5d8742000 4 r---- 0000000000003000 0fd:00000 libattr.so.1.1.0
00007fd5d8743000 4 rw--- 0000000000004000 0fd:00000 libattr.so.1.1.0
00007fd5d8744000 8 r-x-- 0000000000000000 0fd:00000 libdl-2.17.so
00007fd5d8746000 2048 ----- 0000000000002000 0fd:00000 libdl-2.17.so
00007fd5d8946000 4 r---- 0000000000002000 0fd:00000 libdl-2.17.so
00007fd5d8947000 4 rw--- 0000000000003000 0fd:00000 libdl-2.17.so
00007fd5d8948000 384 r-x-- 0000000000000000 0fd:00000 libpcre.so.1.2.0
00007fd5d89a8000 2044 ----- 0000000000060000 0fd:00000 libpcre.so.1.2.0
00007fd5d8ba7000 4 r---- 000000000005f000 0fd:00000 libpcre.so.1.2.0
00007fd5d8ba8000 4 rw--- 0000000000060000 0fd:00000 libpcre.so.1.2.0
00007fd5d8ba9000 1800 r-x-- 0000000000000000 0fd:00000 libc-2.17.so
00007fd5d8d6b000 2048 ----- 00000000001c2000 0fd:00000 libc-2.17.so
00007fd5d8f6b000 16 r---- 00000000001c2000 0fd:00000 libc-2.17.so
00007fd5d8f6f000 8 rw--- 00000000001c6000 0fd:00000 libc-2.17.so
00007fd5d8f71000 20 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5d8f76000 92 r-x-- 0000000000000000 0fd:00000 libpthread-2.17.so
00007fd5d8f8d000 2044 ----- 0000000000017000 0fd:00000 libpthread-2.17.so
00007fd5d918c000 4 r---- 0000000000016000 0fd:00000 libpthread-2.17.so
00007fd5d918d000 4 rw--- 0000000000017000 0fd:00000 libpthread-2.17.so
00007fd5d918e000 16 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5d9192000 84 r-x-- 0000000000000000 0fd:00000 libgcc_s-4.8.5-20150702.so.1
00007fd5d91a7000 2044 ----- 0000000000015000 0fd:00000 libgcc_s-4.8.5-20150702.so.1
00007fd5d93a6000 4 r---- 0000000000014000 0fd:00000 libgcc_s-4.8.5-20150702.so.1
00007fd5d93a7000 4 rw--- 0000000000015000 0fd:00000 libgcc_s-4.8.5-20150702.so.1
00007fd5d93a8000 28 r-x-- 0000000000000000 0fd:00000 librt-2.17.so
00007fd5d93af000 2044 ----- 0000000000007000 0fd:00000 librt-2.17.so
00007fd5d95ae000 4 r---- 0000000000006000 0fd:00000 librt-2.17.so
00007fd5d95af000 4 rw--- 0000000000007000 0fd:00000 librt-2.17.so
00007fd5d95b0000 244 r-x-- 0000000000000000 0fd:00000 libmount.so.1.1.0
00007fd5d95ed000 2044 ----- 000000000003d000 0fd:00000 libmount.so.1.1.0
00007fd5d97ec000 4 r---- 000000000003c000 0fd:00000 libmount.so.1.1.0
00007fd5d97ed000 4 rw--- 000000000003d000 0fd:00000 libmount.so.1.1.0
00007fd5d97ee000 4 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5d97ef000 84 r-x-- 0000000000000000 0fd:00000 libkmod.so.2.2.10
00007fd5d9804000 2044 ----- 0000000000015000 0fd:00000 libkmod.so.2.2.10
00007fd5d9a03000 4 r---- 0000000000014000 0fd:00000 libkmod.so.2.2.10
00007fd5d9a04000 4 rw--- 0000000000015000 0fd:00000 libkmod.so.2.2.10
00007fd5d9a05000 120 r-x-- 0000000000000000 0fd:00000 libaudit.so.1.0.0
00007fd5d9a23000 2044 ----- 000000000001e000 0fd:00000 libaudit.so.1.0.0
00007fd5d9c22000 4 r---- 000000000001d000 0fd:00000 libaudit.so.1.0.0
00007fd5d9c23000 4 rw--- 000000000001e000 0fd:00000 libaudit.so.1.0.0
00007fd5d9c24000 40 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5d9c2e000 52 r-x-- 0000000000000000 0fd:00000 libpam.so.0.83.1
00007fd5d9c3b000 2048 ----- 000000000000d000 0fd:00000 libpam.so.0.83.1
00007fd5d9e3b000 4 r---- 000000000000d000 0fd:00000 libpam.so.0.83.1
00007fd5d9e3c000 4 rw--- 000000000000e000 0fd:00000 libpam.so.0.83.1
00007fd5d9e3d000 16 r-x-- 0000000000000000 0fd:00000 libcap.so.2.22
00007fd5d9e41000 2044 ----- 0000000000004000 0fd:00000 libcap.so.2.22
00007fd5da040000 4 r---- 0000000000003000 0fd:00000 libcap.so.2.22
00007fd5da041000 4 rw--- 0000000000004000 0fd:00000 libcap.so.2.22
00007fd5da042000 144 r-x-- 0000000000000000 0fd:00000 libselinux.so.1
00007fd5da066000 2044 ----- 0000000000024000 0fd:00000 libselinux.so.1
00007fd5da265000 4 r---- 0000000000023000 0fd:00000 libselinux.so.1
00007fd5da266000 4 rw--- 0000000000024000 0fd:00000 libselinux.so.1
00007fd5da267000 8 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5da269000 136 r-x-- 0000000000000000 0fd:00000 ld-2.17.so
00007fd5da479000 40 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5da488000 8 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5da48a000 4 r---- 0000000000021000 0fd:00000 ld-2.17.so
00007fd5da48b000 4 rw--- 0000000000022000 0fd:00000 ld-2.17.so
00007fd5da48c000 4 rw--- 0000000000000000 000:00000 [ anon ]
00007fd5da48d000 1420 r-x-- 0000000000000000 0fd:00000 systemd
00007fd5da7ef000 140 r---- 0000000000162000 0fd:00000 systemd
00007fd5da812000 4 rw--- 0000000000185000 0fd:00000 systemd
00007fd5db8ff000 892 rw--- 0000000000000000 000:00000 [ anon ]
00007ffea366a000 132 rw--- 0000000000000000 000:00000 [ stack ]
00007ffea36b3000 8 r-x-- 0000000000000000 000:00000 [ anon ]
ffffffffff600000 4 r-x-- 0000000000000000 000:00000 [ anon ]
mapped: 43424K writeable/private: 1252K shared: 0K
mapped 表示该进程映射的虚拟地址空间大小,也就是该进程预先分配的虚拟内存大小,即ps出的vsz
writeable/private 表示进程所占用的私有地址空间大小,也就是该进程实际使用的内存大小
shared 表示进程和其他进程共享的内存大小
- 查看进程1的扩展地址
[root@master ~]# pmap -x 1
1: /usr/lib/systemd/systemd --switched-root --system --deserialize 22
Address Kbytes RSS Dirty Mode Mapping
00007fd5d7abc000 16 8 0 r-x-- libuuid.so.1.3.0
00007fd5d7ac0000 2044 0 0 ----- libuuid.so.1.3.0
00007fd5d7cbf000 4 4 4 r---- libuuid.so.1.3.0
00007fd5d7cc0000 4 4 4 rw--- libuuid.so.1.3.0
00007fd5d7cc1000 224 36 0 r-x-- libblkid.so.1.1.0
00007fd5d7cf9000 2048 0 0 ----- libblkid.so.1.1.0
00007fd5d7ef9000 12 12 12 r---- libblkid.so.1.1.0
00007fd5d7efc000 4 4 4 rw--- libblkid.so.1.1.0
00007fd5d7efd000 4 0 0 rw--- [ anon ]
00007fd5d7efe000 84 12 0 r-x-- libz.so.1.2.7
00007fd5d7f13000 2044 0 0 ----- libz.so.1.2.7
00007fd5d8112000 4 4 4 r---- libz.so.1.2.7
00007fd5d8113000 4 4 4 rw--- libz.so.1.2.7
00007fd5d8114000 144 16 0 r-x-- liblzma.so.5.0.99
00007fd5d8138000 2044 0 0 ----- liblzma.so.5.0.99
00007fd5d8337000 4 4 4 r---- liblzma.so.5.0.99
00007fd5d8338000 4 4 4 rw--- liblzma.so.5.0.99
00007fd5d8339000 16 8 0 r-x-- libcap-ng.so.0.0.0
00007fd5d833d000 2048 0 0 ----- libcap-ng.so.0.0.0
00007fd5d853d000 4 4 4 r---- libcap-ng.so.0.0.0
00007fd5d853e000 4 4 4 rw--- libcap-ng.so.0.0.0
00007fd5d853f000 16 8 0 r-x-- libattr.so.1.1.0
00007fd5d8543000 2044 0 0 ----- libattr.so.1.1.0
00007fd5d8742000 4 4 4 r---- libattr.so.1.1.0
00007fd5d8743000 4 4 4 rw--- libattr.so.1.1.0
00007fd5d8744000 8 8 0 r-x-- libdl-2.17.so
00007fd5d8746000 2048 0 0 ----- libdl-2.17.so
00007fd5d8946000 4 4 4 r---- libdl-2.17.so
00007fd5d8947000 4 4 4 rw--- libdl-2.17.so
00007fd5d8948000 384 8 0 r-x-- libpcre.so.1.2.0
00007fd5d89a8000 2044 0 0 ----- libpcre.so.1.2.0
00007fd5d8ba7000 4 4 4 r---- libpcre.so.1.2.0
00007fd5d8ba8000 4 4 4 rw--- libpcre.so.1.2.0
00007fd5d8ba9000 1800 716 0 r-x-- libc-2.17.so
00007fd5d8d6b000 2048 0 0 ----- libc-2.17.so
00007fd5d8f6b000 16 16 16 r---- libc-2.17.so
00007fd5d8f6f000 8 8 8 rw--- libc-2.17.so
00007fd5d8f71000 20 12 12 rw--- [ anon ]
00007fd5d8f76000 92 60 0 r-x-- libpthread-2.17.so
00007fd5d8f8d000 2044 0 0 ----- libpthread-2.17.so
00007fd5d918c000 4 4 4 r---- libpthread-2.17.so
00007fd5d918d000 4 4 4 rw--- libpthread-2.17.so
00007fd5d918e000 16 4 4 rw--- [ anon ]
00007fd5d9192000 84 12 0 r-x-- libgcc_s-4.8.5-20150702.so.1
00007fd5d91a7000 2044 0 0 ----- libgcc_s-4.8.5-20150702.so.1
00007fd5d93a6000 4 4 4 r---- libgcc_s-4.8.5-20150702.so.1
00007fd5d93a7000 4 4 4 rw--- libgcc_s-4.8.5-20150702.so.1
00007fd5d93a8000 28 16 0 r-x-- librt-2.17.so
00007fd5d93af000 2044 0 0 ----- librt-2.17.so
00007fd5d95ae000 4 4 4 r---- librt-2.17.so
00007fd5d95af000 4 4 4 rw--- librt-2.17.so
00007fd5d95b0000 244 112 0 r-x-- libmount.so.1.1.0
00007fd5d95ed000 2044 0 0 ----- libmount.so.1.1.0
00007fd5d97ec000 4 4 4 r---- libmount.so.1.1.0
00007fd5d97ed000 4 4 4 rw--- libmount.so.1.1.0
00007fd5d97ee000 4 4 4 rw--- [ anon ]
00007fd5d97ef000 84 68 0 r-x-- libkmod.so.2.2.10
00007fd5d9804000 2044 0 0 ----- libkmod.so.2.2.10
00007fd5d9a03000 4 4 4 r---- libkmod.so.2.2.10
00007fd5d9a04000 4 4 4 rw--- libkmod.so.2.2.10
00007fd5d9a05000 120 40 0 r-x-- libaudit.so.1.0.0
00007fd5d9a23000 2044 0 0 ----- libaudit.so.1.0.0
00007fd5d9c22000 4 4 4 r---- libaudit.so.1.0.0
00007fd5d9c23000 4 4 4 rw--- libaudit.so.1.0.0
00007fd5d9c24000 40 4 4 rw--- [ anon ]
00007fd5d9c2e000 52 12 0 r-x-- libpam.so.0.83.1
00007fd5d9c3b000 2048 0 0 ----- libpam.so.0.83.1
00007fd5d9e3b000 4 4 4 r---- libpam.so.0.83.1
00007fd5d9e3c000 4 4 4 rw--- libpam.so.0.83.1
00007fd5d9e3d000 16 8 0 r-x-- libcap.so.2.22
00007fd5d9e41000 2044 0 0 ----- libcap.so.2.22
00007fd5da040000 4 4 4 r---- libcap.so.2.22
00007fd5da041000 4 4 4 rw--- libcap.so.2.22
00007fd5da042000 144 68 0 r-x-- libselinux.so.1
00007fd5da066000 2044 0 0 ----- libselinux.so.1
00007fd5da265000 4 4 4 r---- libselinux.so.1
00007fd5da266000 4 4 4 rw--- libselinux.so.1
00007fd5da267000 8 8 8 rw--- [ anon ]
00007fd5da269000 136 112 0 r-x-- ld-2.17.so
00007fd5da479000 40 40 40 rw--- [ anon ]
00007fd5da488000 8 8 8 rw--- [ anon ]
00007fd5da48a000 4 4 4 r---- ld-2.17.so
00007fd5da48b000 4 4 4 rw--- ld-2.17.so
00007fd5da48c000 4 4 4 rw--- [ anon ]
00007fd5da48d000 1420 1196 0 r-x-- systemd
00007fd5da7ef000 140 132 132 r---- systemd
00007fd5da812000 4 4 4 rw--- systemd
00007fd5db8ff000 892 844 844 rw--- [ anon ]
00007ffea366a000 132 52 52 rw--- [ stack ]
00007ffea36b3000 8 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------- ------- -------
total kB 43424 3820 1292