understanding pmap output

Arka picture Arka · Mar 22, 2012 · Viewed 33.8k times · Source

I was trying to see memory map of a process on Linux x86-64 using pmap -x command. I got confused looking at the output of the pmap. Particularly for the entries for mapping dynamic libraries. There are multiple entries for them (actually 4 for all most all of them, with some having 3 entries). Following is an example

  Address           Kbytes   RSS   Dirty Mode   Mapping

00000036ca200000      88      64       0 r-x--  libpthread-2.5.so
00000036ca216000    2044       0       0 -----  libpthread-2.5.so
00000036ca415000       4       4       4 r----  libpthread-2.5.so
00000036ca416000       4       4       4 rw---  libpthread-2.5.so

The second row for each of the library always has size of 2MB while it has no page permission. Across all libraries it seems its RSS is ALWAYS zero. Last two rows also have same size (which is base page size) and same permissions (a handful libraries does not have rw mapping).

Does anybody has some explanation for this? I am kind of having a sense that possibly the mapping with the read-only protection is done by the loader to read the metadata of the library while the portion with the executable permission actually the code for the library. I may be wrong though.

But I have no clue about that middle row. No permission and no usages? Anyone has some words of wisdom here?

I also saw a few pages reported to be on the anonymous memory and not have any mode bit set. What do these represent?

Answer

user5479960 picture user5479960 · Oct 23, 2015

These protected "----" pages are guard pages to prevent pointers from indexing between the code and data segments of the library. They only exist in the virtual space of the process and exist to cause a fault if a pointer walks past the end of the segment.

If these weren't addressed into a shared library file I would say they were serving as a buffer for expanding allocations into e.g. malloc or stack growth. For example glibc requests large chunks of address space from the kernel for thread-local allocation arenas then consumes them slowly for malloc'd allocations. In a much larger pmap from a JVM I'm looking at there are a few dozen of these, each following a RW page or filling in the space between two large RW allocations and the boundaries between them shift as the RW pages expand. On X86_64 guard pages like this can use the CPU's memory protection system to catch bad pointer dereferences.