文件 ---- /proc/<PID>/maps
查看进程的虚拟地址空间是如何使用的。
该文件有6列,分别为:
地址:库在进程里地址范围
权限:虚拟内存的权限,r=读,w=写,x=执行,s=共享,p=私有;
偏移量:库在进程里地址偏移量
设备:映像文件的主设备号和次设备号,可以通过通过 cat /proc/devices查看设备号对应的设备名
节点:映像文件的节点号;
路径: 映像文件的路径,经常同一个地址有两个地址范围,那是因为一段是r-xp为只读的代码段,一段是rwxp为可读写的数据段。
每项都与一个vm_area_struct结构成员对应
下面举个例子
应用程序xpashell的代码段范围是08048000-09138000,大小为4096字节;数据段范围是09138000-0940e000,大小为2D6000字节。在看共享库libnss_files.so.2,其代码段和数据段分别为f5a52000-f5a5a000 和 f5a5a000-f5a5b000
[root@localhost ~]# cat /proc/7465/maps
08048000-09138000 r-xp 00000000 08:03 9814092 /home/apple/xpashell/bin/xpashell
09138000-0940e000 rwxp 010f0000 08:03 9814092 /home/apple/xpashell/bin/xpashell
0940e000-0963e000 rwxp 0940e000 00:00 0 [heap]
f23a5000-f23a6000 ---p f23a5000 00:00 0
f23a6000-f2ba6000 rwxp f23a6000 00:00 0
f2ba6000-f2ba7000 ---p f2ba6000 00:00 0
f2ba7000-f33a7000 rwxp f2ba7000 00:00 0
f33a7000-f33a8000 ---p f33a7000 00:00 0
f33a8000-f3ba8000 rwxp f33a8000 00:00 0
f3ba8000-f3ba9000 ---p f3ba8000 00:00 0
f3ba9000-f48fe000 rwxp f3ba9000 00:00 0
f48fe000-f48ff000 ---p f48fe000 00:00 0
f48ff000-f50ff000 rwxp f48ff000 00:00 0
f50ff000-f5100000 ---p f50ff000 00:00 0
f5100000-f5900000 rwxp f5100000 00:00 0
f5900000-f5a00000 rwxp f5900000 00:00 0
f5a52000-f5a5a000 r-xp 00000000 08:02 5821326 /lib/jix/32/libnss_files.so.2
f5a5a000-f5a5b000 rwxp 00007000 08:02 5821326 /lib/jix/32/libnss_files.so.2
f5a5b000-f5aca000 rwxp f5a5b000 00:00 0
f5aca000-f5acb000 ---p f5aca000 00:00 0
f5acb000-f62cb000 rwxp f5acb000 00:00 0
f62cb000-f62cc000 ---p f62cb000 00:00 0
f62cc000-f6acc000 rwxp f62cc000 00:00 0
f6acc000-f6acd000 ---p f6acc000 00:00 0
f6acd000-f72ce000 rwxp f6acd000 00:00 0
f72ce000-f72cf000 ---p f72ce000 00:00 0
f72cf000-f7ad1000 rwxp f72cf000 00:00 0
f7ad1000-f7ad3000 r-xp 00000000 08:02 5821320 /lib/jix/32/libdl.so.2
f7ad3000-f7ad4000 rwxp 00001000 08:02 5821320 /lib/jix/32/libdl.so.2
f7ad4000-f7adb000 r-xp 00000000 08:02 5821329 /lib/jix/32/librt.so.1
f7adb000-f7adc000 rwxp 00006000 08:02 5821329 /lib/jix/32/librt.so.1
f7adc000-f7add000 rwxp f7adc000 00:00 0
f7add000-f7be5000 r-xp 00000000 08:02 5821317 /lib/jix/32/libc.so.6
f7be5000-f7bed000 rwxp 00108000 08:02 5821317 /lib/jix/32/libc.so.6
f7bed000-f7bef000 rwxp f7bed000 00:00 0
f7bef000-f7bf7000 r-xp 00000000 08:02 5821321 /lib/jix/32/libgcc_s.so.1
f7bf7000-f7bf8000 rwxp 00007000 08:02 5821321 /lib/jix/32/libgcc_s.so.1
f7bf8000-f7c19000 r-xp 00000000 08:02 5821323 /lib/jix/32/libm.so.6
f7c19000-f7c1a000 rwxp 00020000 08:02 5821323 /lib/jix/32/libm.so.6
f7c1a000-f7cca000 r-xp 00000000 08:02 5821330 /lib/jix/32/libstdc++.so.6
f7cca000-f7ce1000 rwxp 000b0000 08:02 5821330 /lib/jix/32/libstdc++.so.6
f7ce1000-f7ce7000 rwxp f7ce1000 00:00 0
f7ce7000-f7e0e000 r-xp 00000000 08:02 5821331 /lib/jix/32/libxml2.so.2
f7e0e000-f7e13000 rwxp 00126000 08:02 5821331 /lib/jix/32/libxml2.so.2
f7e13000-f7e14000 rwxp f7e13000 00:00 0
f7e14000-f7f2a000 r-xp 00000000 08:02 5821316 /lib/jix/32/libboost_regex-gcc-mt-d-1_33.so.1.33.0
f7f2a000-f7f45000 rwxp 00116000 08:02 5821316 /lib/jix/32/libboost_regex-gcc-mt-d-1_33.so.1.33.0
f7f45000-f7f46000 rwxp f7f45000 00:00 0
f7f46000-f7f48000 r-xp 00000000 08:02 5821318 /lib/jix/32/libcharset.so.1
f7f48000-f7f49000 rwxp 00001000 08:02 5821318 /lib/jix/32/libcharset.so.1
f7f49000-f7f57000 r-xp 00000000 08:02 5821327 /lib/jix/32/libpthread.so.0
f7f57000-f7f58000 rwxp 0000e000 08:02 5821327 /lib/jix/32/libpthread.so.0
f7f58000-f7f5b000 rwxp f7f58000 00:00 0
f7f5b000-f7f70000 r-xp 00000000 08:02 5821315 /lib/jix/32/ld-linux.so.2
f7f70000-f7f71000 rwxp 00014000 08:02 5821315 /lib/jix/32/ld-linux.so.2
ffe5f000-ffe6a000 rw-p ffe5f000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0
[root@localhost ~]#
各共享库的代码段,存放着二进制可执行的机器指令,是由kernel把该库ELF文件的代码段map到虚存空间;
各共享库的数据段,存放着程序执行所需的全局变量,是由kernel把ELF文件的数据段map到虚存空间;
用户代码段,存放着二进制形式的可执行的机器指令,是由kernel把ELF文件的代码段map到虚存空间;
用户数据段,存放着程序执行所需的全局变量,是由kernel把ELF文件的数据段map到虚存空间;
堆(heap),当且仅当malloc调用时存在,是由kernel把匿名内存map到虚存空间,堆则在程序中没有调用malloc的情况下不存在;
栈(stack),作为进程的临时数据区,是由kernel把匿名内存map到虚存空间,栈空间的增长方向是从高地址到低地址。
xms-hmos:/proc/7465 # ldd /home/apple/xpashell/bin/xpashell
linux-gate.so.1 => (0xffffe000)
libpthread.so.0 => /lib/jix/32/libpthread.so.0 (0xf7f6f000)
libcharset.so.1 => /lib/jix/32/libcharset.so.1 (0xf7f6c000)
libboost_regex-gcc-mt-d-1_33.so.1.33.0 => /lib/jix/32/libboost_regex-gcc-mt-d-1_33.so.1.33.0 (0xf7e3a000)
libxml2.so.2 => /lib/jix/32/libxml2.so.2 (0xf7d0d000)
libstdc++.so.6 => /lib/jix/32/libstdc++.so.6 (0xf7c40000)
libm.so.6 => /lib/jix/32/libm.so.6 (0xf7c1e000)
libgcc_s.so.1 => /lib/jix/32/libgcc_s.so.1 (0xf7c15000)
libc.so.6 => /lib/jix/32/libc.so.6 (0xf7b03000)
/lib/jix/32/ld-linux.so.2 (0xf7f81000)
librt.so.1 => /lib/jix/32/librt.so.1 (0xf7afa000)
libdl.so.2 => /lib/jix/32/libdl.so.2 (0xf7af7000)
通过ldd命令可以看到其依赖的库,这里的"linux-gate.so.1"的内容就是内核映射的代码,系统中其实并不存在这样一个链接库文件,而是ldd虚拟的,0xffffe000这里就是内核为我们映射的系统调用入口代码。