一.示例代碼:
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占用的空間大小,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/244003.html
標籤:其他
