![/proc/pid/maps 주소(및 번역)](https://linux55.com/image/53651/%2Fproc%2Fpid%2Fmaps%20%EC%A3%BC%EC%86%8C(%EB%B0%8F%20%EB%B2%88%EC%97%AD).png)
/proc/pid/maps의 메모리 맵을 보면 다양한 길이의 주소를 볼 수 있습니다.
00400000-0042e000 r-xp 00000000 fb:01 268953 /bin/nano
0062e000-0062f000 r--p 0002e000 fb:01 268953 /bin/nano
0062f000-00630000 rw-p 0002f000 fb:01 268953 /bin/nano
0081e000-00906000 rw-p 00000000 00:00 0 [heap]
7f8313e5c000-7f8314109000 rw-p 00000000 fb:01 2399989 /usr/share/misc/magic.mgc
7f8314109000-7f83142ce000 r--p 00000000 fb:01 2759354 /usr/lib64/locale/locale-archive
7f83142ce000-7f83142d1000 r-xp 00000000 fb:01 1457046 /lib64/libdl-2.17.so
7f83142d1000-7f83144d0000 ---p 00003000 fb:01 1457046 /lib64/libdl-2.17.so
예를 들어, 8비트 길이의 주소가 있습니다.
- 00400000-0042e000
및 12비트 길이(마지막 3비트는 항상 0임):
- 7f8313e5c000-7f8314109000
주소가 이 형식인 이유는 무엇입니까? 8비트 길이로 변환할 수 있나요?
답변1
첫째, 주소를 8자리로만 변환할 수는 없습니다. 메모리 주소는 단지 8비트 숫자로 표현할 수 있는 것보다 훨씬 더 큰 값을 가질 수 있고 가질 것입니다.
/proc/pid/maps
메모리 주소가 있는 그대로 표시되는 이유는 fs/proc/task_mmu.c
최신 커널 소스 트리의 283행에 있습니다(또는).task_nommu.c
283 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
284 start,
285 end,
286 flags & VM_READ ? 'r' : '-',
287 flags & VM_WRITE ? 'w' : '-',
288 flags & VM_EXEC ? 'x' : '-',
289 flags & VM_MAYSHARE ? 's' : 'p',
290 pgoff,
291 MAJOR(dev), MINOR(dev), ino);
이것이 요약되는 것은 16진수 문자열 표현이 8자리보다 짧은 모든 메모리 주소가 앞에 0으로 채워진다는 것입니다. 이보다 큰 값은 8자리로 잘리지 않고 있는 그대로 표시됩니다. 이것이 printk()
printf 스타일 형식이 작동하는 방식입니다.
이제 이 모든 것에서 무엇을 얻을 수 있습니까? 어쩌면 메모리 주소가 8자리로 잘리는 이유에 대해 잠시 생각해 봐야 할 것입니다. 이 일을 하면 어떤 이점이 있다고 생각하시나요?
답변2
이러한 주소는 원래대로여야 하며, 잘릴 수 있는 것으로 취급하면 안 됩니다. 이러한 열의 의미에 대해 자세히 알아보려면 매뉴얼 페이지를 확인 man proc
하고 파일 내용을 읽어보세요 ./proc/<pid>/maps
발췌
/proc/[pid]/maps
A file containing the currently mapped memory regions and their
access permissions. See mmap(2) for some further information
about memory mappings.
The format of the file is:
address perms offset dev inode pathname
00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
00651000-00652000 r--p 00051000 08:02 173521 /usr/bin/dbus-daemon
00652000-00655000 rw-p 00052000 08:02 173521 /usr/bin/dbus-daemon
00e03000-00e24000 rw-p 00000000 00:00 0 [heap]
00e24000-011f7000 rw-p 00000000 00:00 0 [heap]
...
35b1800000-35b1820000 r-xp 00000000 08:02 135522 /usr/lib64/ld-2.15.so
35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522 /usr/lib64/ld-2.15.so
이 출력에는 선행 0이 표시되지 않기 때문에 주소가 이런 방식으로 표시됩니다. 내가 작성한 이 대략적인 명령을 사용하여 awk
올바른 앞에 오는 0을 출력에 다시 넣어 모든 것이 고려된 전체 주소 공간에 맞춰 정렬된 것처럼 보이도록 할 수 있습니다.
$ awk '{split($1,a,"-"); $1=sprintf("%16s-%16s",a[1],a[2]); gsub(/ /,"0",$1); \
printf "%33s %4s %8s %5s %-6s %7s\n",$1,$2,$3,$4,$5,$6}' \
/proc/<pid>/maps
예
다음은 내 시스템의 샘플 지도 파일입니다.
앞으로
$ tail -10 /proc/1607/maps
7f6c3a247000-7f6c3a248000 rw-p 00021000 fd:01 526702 /usr/lib64/ld-2.17.so
7f6c3a248000-7f6c3a249000 rw-p 00000000 00:00 0
7f6c3a249000-7f6c3a2ad000 r-xp 00000000 fd:01 529820 /usr/bin/dbus-daemon
7f6c3a4ac000-7f6c3a4ae000 r--p 00063000 fd:01 529820 /usr/bin/dbus-daemon
7f6c3a4ae000-7f6c3a4af000 rw-p 00065000 fd:01 529820 /usr/bin/dbus-daemon
7f6c3a68a000-7f6c3a6ab000 rw-p 00000000 00:00 0 [heap]
7f6c3a6ab000-7f6c3aace000 rw-p 00000000 00:00 0 [heap]
7fffce239000-7fffce25a000 rw-p 00000000 00:00 0 [stack]
7fffce3fe000-7fffce400000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
뒤쪽에
$ awk '{split($1,a,"-"); $1=sprintf("%16s-%16s",a[1],a[2]); gsub(/ /,"0",$1); \
printf "%33s %4s %8s %5s %-6s %7s\n",$1,$2,$3,$4,$5,$6}' \
<(tail /proc/1607/maps)
00007f6c3a247000-00007f6c3a248000 rw-p 00021000 fd:01 526702 /usr/lib64/ld-2.17.so
00007f6c3a248000-00007f6c3a249000 rw-p 00000000 00:00 0
00007f6c3a249000-00007f6c3a2ad000 r-xp 00000000 fd:01 529820 /usr/bin/dbus-daemon
00007f6c3a4ac000-00007f6c3a4ae000 r--p 00063000 fd:01 529820 /usr/bin/dbus-daemon
00007f6c3a4ae000-00007f6c3a4af000 rw-p 00065000 fd:01 529820 /usr/bin/dbus-daemon
00007f6c3a68a000-00007f6c3a6ab000 rw-p 00000000 00:00 0 [heap]
00007f6c3a6ab000-00007f6c3aace000 rw-p 00000000 00:00 0 [heap]
00007fffce239000-00007fffce25a000 rw-p 00000000 00:00 0 [stack]
00007fffce3fe000-00007fffce400000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]