pmap 출력의 의미


12

나는 main.c리눅스에서 썼다 :

int main()
{
  while (1){}
}

컴파일하고 시작할 때 할 수 pmap있습니다.

# pmap 28578
28578:   ./a.out
0000000000400000      4K r-x--  /root/a.out
0000000000600000      4K r----  /root/a.out
0000000000601000      4K rw---  /root/a.out
00007f87c16c2000   1524K r-x--  /lib/libc-2.11.1.so
00007f87c183f000   2044K -----  /lib/libc-2.11.1.so
00007f87c1a3e000     16K r----  /lib/libc-2.11.1.so
00007f87c1a42000      4K rw---  /lib/libc-2.11.1.so
00007f87c1a43000     20K rw---    [ anon ]
00007f87c1a48000    128K r-x--  /lib/ld-2.11.1.so
00007f87c1c55000     12K rw---    [ anon ]
00007f87c1c65000      8K rw---    [ anon ]
00007f87c1c67000      4K r----  /lib/ld-2.11.1.so
00007f87c1c68000      4K rw---  /lib/ld-2.11.1.so
00007f87c1c69000      4K rw---    [ anon ]
00007fff19b82000     84K rw---    [ stack ]
00007fff19bfe000      8K r-x--    [ anon ]
ffffffffff600000      4K r-x--    [ anon ]
 total             3876K

총계 (3876)를 K로 나눈 값 VIRT은의 출력 에서 열과 같습니다 top. 이제 텍스트 세그먼트는 어디에 있습니까? 400000, 600000, 601000 에서요? 어디에 있는지 설명을 어디서 읽을 수 있습니까? man pmap도와주지 않았다.


텍스트 세그먼트는 실제로 읽기 전용이므로 0000000000600000입니다.
Danila Ladner

감사! 텍스트 세그먼트도 실행 가능하지 않아야합니까?
Thorsten Staerk

1
그래 당신 말이 맞아요. r과 rx. 0000000000400000도 마찬가지입니다.
Danila Ladner

답변:


15

텍스트 세그먼트는 0x400000에서의 매핑입니다. 읽기 및 실행 가능하도록 'rx'로 표시되어 있습니다. 0x600000에서의 매핑은 읽기 전용이므로 실행 파일의 ".rodata"섹션이 거의 확실합니다. GCC는 C 문자열 리터럴을 읽기 전용 섹션에 넣습니다. 0x601000의 매핑은 'rw-'이므로 유명한 힙일 것입니다. 실행 파일을 malloc()1024 바이트로 설정하고 주소를 인쇄하여 확인할 수 있습니다.

프로세스의 PID를 찾고 다음을 수행하여 조금 더 많은 정보를 얻을 수 있습니다.- cat /proc/$PID/maps내 Arch 랩톱에서 추가 정보를 제공합니다. 그것은 3.12 커널을 실행하고 있기 때문에 /proc/$PID/numa_maps작은 통찰력을 줄 수있는 catting도 있습니다.

실행 파일에서 실행할 기타 사항 : nmobjdump -x. 전자는 메모리 맵에서 다양한 것들이 어디에 있는지에 대한 아이디어를 줄 수 있으므로 0x4000000 섹션과 다른 섹션의 내용을 볼 수 있습니다. objdump -x많은 다른 것들 중에서 ELF 파일 헤더를 보여 주므로 모든 섹션을 볼 수 있으며 섹션 이름과 런타임에 매핑되었는지 여부를 모두 볼 수 있습니다.

"어디에 있는지"에 대한 서면 설명을 찾는 한 "ELF FILE 메모리 레이아웃"에 대해 Google과 같은 작업을 수행해야합니다. ELF 파일 형식은 일반적으로 사용되는 것보다 더 이국적인 메모리 레이아웃을 지원할 수 있습니다. GCC와 Gnuld 및 glibc는 모두 실행 파일이 어떻게 배치되고 런타임에 메모리에 매핑되는지에 대한 간단한 가정을합니다. 이를 문서화하기위한 많은 웹 페이지가 존재하지만 이전 버전의 Linux, 이전 버전의 GCC 또는 glibc에만 적용되거나 x86 실행 파일에만 적용됩니다. 없는 경우 readelf명령을 받으십시오 . C 프로그램을 작성할 수 있다면, 자신의 버전을 만들 objdump -x거나 readelf실행 파일의 작동 방식과 그 내용을 숙지하십시오.


2
좋은 대답입니다. 이제 프로그램의 힙은 어디에 있습니까? 그리고 이것이 무엇을 의미합니까? 이것을 찾으려면 Google에 무엇을해야합니까?
Thorsten Staerk

1
그거 알아? 0x601000 주소 매핑이 잘못되었습니다. 아마도 힙일 것입니다. 당신은 그것을 사용 readelf하거나 objdump알아 내야하며, 당신이 만든 실행 파일을 무엇이든 사용해야 합니다. 내 아치 리눅스 상자는 /usr/lib/libc-2.18.so를 사용하므로 상자와는 다릅니다.
Bruce Ediger

2
0x601000데이터 세그먼트입니다. 그것은 포함 .data, .bss과를 통해 확장 할 수 있습니다 brk(). [anon]를 통해 얻은 비 파일 백업 메모리 (스왑으로 백업)를 나타냅니다 mmap(). dlmalloc은 brk()~ 64Kb IIRC보다 작은 할당과 mmap()더 큰 할당에 사용합니다. 힙은 malloc에 ​​의해 데이터 세그먼트의 확장 부분 및 mmap()기반 할당 모두에 의해 할당 된 모든 것 입니다.
ninjalj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.