linux下/proc/pid/和pmap命令詳解

一.示例代碼:

1.創建pmap.c文件:

vi pmap.c

2.輸入如下內容:

#inculde <stdio.h>
int main()
{
   
   
        char *str;
        str = (char *) malloc(15);
        while(1)
        {
   
   
                ;
        }
        return 0;
}

3.編譯pmap.c文件:

gcc pmap.c -o pmap

4.運行pmap可執行文件

./pmap

二.查看/proc/pid/maps文件信息

1.找到pmap進程的pid號:

$ps aux |grep pmap

2.打印輸出/proc/pid/maps文件信息:

cat /proc/565/maps

輸出結果如下:

08048000-08049000 r-xp 00000000 08:03 5636417    /root/test/pmap
08049000-0804a000 rw-p 00000000 08:03 5636417    /root/test/pmap
0952c000-0954d000 rw-p 00000000 00:00 0          [heap]
77573000-77574000 rw-p 00000000 00:00 0
77574000-77723000 r-xp 00000000 08:03 262816     /lib/libc-2.21.so
77723000-77726000 r--p 001ae000 08:03 262816     /lib/libc-2.21.so
77726000-77728000 rw-p 001b1000 08:03 262816     /lib/libc-2.21.so
77728000-7772a000 rw-p 00000000 00:00 0
7772f000-77730000 rw-p 00000000 00:00 0
77730000-77732000 r--p 00000000 00:00 0          [vvar]
77732000-77733000 r-xp 00000000 00:00 0          [vdso]
77733000-77754000 r-xp 00000000 08:03 262539     /lib/ld-2.21.so
77754000-77755000 r--p 00021000 08:03 262539     /lib/ld-2.21.so
77755000-77756000 rw-p 00022000 08:03 262539     /lib/ld-2.21.so
7fcad000-7fcce000 rw-p 00000000 00:00 0          [stack]

輸出的信息依次爲:
第一列:本段在虛擬內存中的地址範圍。
第二列:本段的權限。
第三列:偏移地址,即指本段映射地址在文件中的偏移。
第四列:主設備號與次設備號。
第五列:文件索引節點號。
第六列:映射的文件名。
經過上面的分析,proc maps中的每一列代表的意思已經非常清晰了。接下來看下proc每maps中每一行的解析。各共享庫的代碼段,存放着二進制可執行的機器指令,由kernel把該庫ELF文件的代碼段map到虛存空間;各共享庫的數據段,存放着程序執行所需的全局變量,由kernel把ELF文件的數據段map到虛存空間;用戶代碼段,存放着二進制形式的可執行的機器指令,由kernel把ELF文件的代碼段map到虛存空間;用戶數據段,存放着程序執行所需的全局變量,由kernel把ELF文件的數據段map到虛存空間;堆(heap),當且僅當malloc調用時存在,由kernel把匿名內存map到虛存空間,堆則在程序中沒有調用malloc的情況下不存在;棧(stack),作爲進程的臨時數據區,由kernel把匿名內存map到虛存空間,棧空間的增長方向是從高地址到低地址。






08048000-08049000 r-xp 00000000 08:03 5636417    /root/test/pmap
08049000-0804a000 rw-p 00000000 08:03 5636417    /root/test/pmap

其中第一行的權限是隻讀,並且可執行,說明第一行是應用程序的代碼段,而第二行的權限是可讀可寫,但是沒有執行權限,說明該段是數據段。

0952c000-0954d000 rw-p 00000000 00:00 0          [heap]

有些maps文件並不會出現該記錄,這主要跟程序中有無使用malloc相關,如果程序中使用了malloc就會有該記錄,否則就沒有。

77573000-77574000 rw-p 00000000 00:00 0

這一段是bss段。

77574000-77723000 r-xp 00000000 08:03 262816     /lib/libc-2.21.so
77723000-77726000 r--p 001ae000 08:03 262816     /lib/libc-2.21.so
77726000-77728000 rw-p 001b1000 08:03 262816     /lib/libc-2.21.so
77728000-7772a000 rw-p 00000000 00:00 0

以上是libc-2.21共享庫在maps文件中的記錄,每個共享庫在maps文件中對應着三行,分別是數據段與代碼段。第四行是bss段。

7fcad000-7fcce000 rw-p 00000000 00:00 0          [stack]

該段是棧。

77732000-77733000 r-xp 00000000 00:00 0          [vdso]

該段表示它的地址已經位於內核空間了(即大於0xc0000000的地址),事實上它是一個內核的模塊,進程可以通過訪問這一個段來與內核通信。

三.pmap命令的使用

1.pmap命令的介紹:
-x extended顯示擴展格式
-d device顯示設備格式
-q quiet不顯示header/footer行
-V 顯示版本信息
2.pmap命令使用詳解:
輸入pmap -d 565
輸出信息如下:






565:   ./pmap
Address   Kbytes Mode  Offset           Device    Mapping
08048000       4 r-x-- 0000000000000000 008:00003 pmap
08049000       4 rw--- 0000000000000000 008:00003 pmap
0952c000     132 rw--- 0000000000000000 000:00000   [ anon ]
77573000       4 rw--- 0000000000000000 000:00000   [ anon ]
77574000    1724 r-x-- 0000000000000000 008:00003 libc-2.21.so
77723000      12 r---- 00000000001ae000 008:00003 libc-2.21.so
77726000       8 rw--- 00000000001b1000 008:00003 libc-2.21.so
77728000       8 rw--- 0000000000000000 000:00000   [ anon ]
7772f000       4 rw--- 0000000000000000 000:00000   [ anon ]
77730000       8 r---- 0000000000000000 000:00000   [ anon ]
77732000       4 r-x-- 0000000000000000 000:00000   [ anon ]
77733000     132 r-x-- 0000000000000000 008:00003 ld-2.21.so
77754000       4 r---- 0000000000021000 008:00003 ld-2.21.so
77755000       4 rw--- 0000000000022000 008:00003 ld-2.21.so
7fcad000     132 rw--- 0000000000000000 000:00000   [ stack ]
mapped: 2184K    writeable/private: 296K    shared: 0K

Address: 內存開始地址
Kbytes: 佔用內存的字節數(KB)
RSS: 保留內存的字節數(KB)
Dirty: 髒頁的字節數(包括共享和私有的)(KB)
Mode: 內存的權限:read、write、execute、shared、private (寫時複製)
Mapping: 佔用內存的文件、或[anon](分配的內存)、或[stack](堆棧)
Offset: 文件偏移
Device: 設備名 (major:minor)
最後一行的值







mapped :表示該進程映射的虛擬地址空間大小,也就是該進程預先分配的虛擬內存大小。

writeable/private : 表示進程所佔用的私有地址空間大小,也就是該進程實際使用的內存大小。

shared: 表示進程和其他進程共享的內存大小。
注意:共享庫只在內存中有一份,是所有進程共享的,這裏該進程實際佔用空間大小爲writeable/private佔用的空間大小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章