简介

在这篇文章中,我介绍了如何观察一个进程的地址空间,也就是maps

https://storebarrel1-1308416823.cos.ap-shanghai.myqcloud.com/img/pexels-davor-eres-8230225.jpg

参考

https://man7.org/linux/man-pages/man5/proc.5.html

感谢

Photo by Davor Eres: https://www.pexels.com/photo/brown-and-white-duck-on-water-8230225/

操作

代码

代码内容如下

simplest_main.c

1
2
3
4
int main(){
while(1);
return 0;
}

实验过程

在一个shell中执行这个程序,再打开另一个shell,首先查看pid,然后通过proc/pid/maps和pmap命令两种方式来观察这个进程的maps情况

如下所示,这个pid是187777,通过两种方式来观察,首先是proc/187777/maps文件,来看看内核给我们提供的信息,然后是通过pmap命令,pmap命令有很多中选项,这里选择了简单的-d选项,具体的含义可以参考help说明,同时,还有一个-XX的选项,是最详细的信息,内容实在是太多了,我放到了github中,看起来方便

实验结果观察

查看进程pid

1
2
3
4
5
6
[liode@fedora:2:~]$ ps -a
PID TTY TIME CMD
1451 tty2 00:04:25 Xorg
1462 tty2 00:00:00 gnome-session-b
187777 pts/2 00:00:18 simplest_main
187869 pts/3 00:00:00 ps

通过proc观察

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[liode@fedora:3:~]$ cat /proc/187777/maps
00400000-00401000 r-xp 00000000 00:3f 30052196 /media/psf/Home/MyTec/gitrepos/kernel/process/simplest_main
0041f000-00420000 r--p 0000f000 00:3f 30052196 /media/psf/Home/MyTec/gitrepos/kernel/process/simplest_main
00420000-00421000 rw-p 00010000 00:3f 30052196 /media/psf/Home/MyTec/gitrepos/kernel/process/simplest_main
ffff96430000-ffff965bd000 r-xp 00000000 00:21 353728 /usr/lib64/libc.so.6
ffff965bd000-ffff965cc000 ---p 0018d000 00:21 353728 /usr/lib64/libc.so.6
ffff965cc000-ffff965d0000 r--p 0018c000 00:21 353728 /usr/lib64/libc.so.6
ffff965d0000-ffff965d2000 rw-p 00190000 00:21 353728 /usr/lib64/libc.so.6
ffff965d2000-ffff965d9000 rw-p 00000000 00:00 0
ffff965f3000-ffff9661d000 r-xp 00000000 00:21 353725 /usr/lib/ld-linux-aarch64.so.1
ffff9662c000-ffff9662e000 rw-p 00000000 00:00 0
ffff9662e000-ffff96630000 r--p 00000000 00:00 0 [vvar]
ffff96630000-ffff96631000 r-xp 00000000 00:00 0 [vdso]
ffff96631000-ffff96633000 r--p 0002e000 00:21 353725 /usr/lib/ld-linux-aarch64.so.1
ffff96633000-ffff96635000 rw-p 00030000 00:21 353725 /usr/lib/ld-linux-aarch64.so.1
ffffd7894000-ffffd78b5000 rw-p 00000000 00:00 0 [stack]
[liode@fedora:4:~]$

通过pmap观察

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[liode@fedora:6:~]$ pmap 187777 -d
187777: ./simplest_main
Address Kbytes Mode Offset Device Mapping
0000000000400000 4 r-x-- 0000000000000000 000:0003f simplest_main
000000000041f000 4 r---- 000000000000f000 000:0003f simplest_main
0000000000420000 4 rw--- 0000000000010000 000:0003f simplest_main
0000ffff96430000 1588 r-x-- 0000000000000000 000:00021 libc.so.6
0000ffff965bd000 60 ----- 000000000018d000 000:00021 libc.so.6
0000ffff965cc000 16 r---- 000000000018c000 000:00021 libc.so.6
0000ffff965d0000 8 rw--- 0000000000190000 000:00021 libc.so.6
0000ffff965d2000 28 rw--- 0000000000000000 000:00000 [ anon ]
0000ffff965f3000 168 r-x-- 0000000000000000 000:00021 ld-linux-aarch64.so.1
0000ffff9662c000 8 rw--- 0000000000000000 000:00000 [ anon ]
0000ffff9662e000 8 r---- 0000000000000000 000:00000 [ anon ]
0000ffff96630000 4 r-x-- 0000000000000000 000:00000 [ anon ]
0000ffff96631000 8 r---- 000000000002e000 000:00021 ld-linux-aarch64.so.1
0000ffff96633000 8 rw--- 0000000000030000 000:00021 ld-linux-aarch64.so.1
0000ffffd7894000 132 rw--- 0000000000000000 000:00000 [ stack ]
mapped: 2048K writeable/private: 188K shared: 0K
详细观察的命令如下
pmap 18777 -XX
输出最详细的信息,内容太多了,我放到了githhub上

https://github.com/liodegwin/kernel/blob/main/process/pmap_everything.txt

解析

proc/pid/maps

可以看到每一行都是一个VMA,对应一个内核中vm_area_struct结构,在我这个情况下,一共有15行,也就是15个vma

那么具体来看看每一个vma都具有哪些信息喽,

队医proc/pid/maps中输出的每一个列和含义,可以从man pages中查看到详细解释,如下

https://man7.org/linux/man-pages/man5/proc.5.html

首先当然是address和lenth了,这非常好理解,这里可以观察到,都是4k的倍数了,因为是4k的page大小原因,其他倒是没什么可说的了

然后是prem或者mode这个列,是权限的意思,rwx读写执行,很容易理解,p的话是private的意思了,如果一个进程里面的多个线程,那他们就会共享一些数据,会观察到那些线程里面有一些vma就不是p的

值得注意的是,使用proc里面和pmap -XX输出的格式,这一列都是有p的,而pmap -d根本就没有p这个权限,而且它是5个位置,暂时我不知道为啥,

然后是offset,这个是对于什么的偏移啊?对于path name这一列对应的文件的偏移喽,如果这个vma不对应一个文件,这个偏移就是0

然后是设备号

这个很好理解,没什么好说的,和offset一样,如果path name这一列有的话,设备号才有意义,不然就是个0

然后是设备的inode

这个和offset和设备号都是一样的,都只有在对应一个文件/设备的时候才有意义,不然就是0

最后是path name

这一列是设备路径,如果对应一个设备的话,就是路径,如果没有的话,要么干脆就是空白的,像是proc中的那样,要么就是写上了[anon],像是

pmap