Skip to main content
Adam Leventhal's Blog

Number 18 of 20: pmap(1) improvements

go to the Solaris 10 top 11-20 list for more

pmap(1)

For the uninitiated, pmap(1) is a tool that lets you observe the mappings in a process. Here's some typical output:

311981: /usr/bin/sh
08046000       8K rw--- [ stack ]
08050000      80K r-x-- /sbin/sh
08074000       4K rwx-- /sbin/sh
08075000      16K rwx-- [ heap ]
C2AB0000      64K rwx-- [ anon ]
C2AD0000     752K r-x-- /lib/libc.so.1
C2B9C000      28K rwx-- /lib/libc.so.1
C2BA3000      16K rwx-- /lib/libc.so.1
C2BB1000       4K rwxs- [ anon ]
C2BC0000     132K r-x-- /lib/ld.so.1
C2BF1000       4K rwx-- /lib/ld.so.1
C2BF2000       8K rwx-- /lib/ld.so.1
total      1116K

You can use this to understand various adresses you might see from a debugger, or you can use other modes of pmap(1) to see the page sizes being used for various mappings, how much of the mappings have actually been faulted in, the attached ISM, DISM or System V shared memory segments, etc. In Solaris 10, pmap(1) has some cool new features -- after a little more thought, I'm not sure that this really belongs on the top 11-20 list, but this is a very cool tool and gets some pretty slick new features; anyways the web affords me the chance for some revisionist history if I feel like updating the list...

thread and signal stacks

When a process creates a new thread, that thread needs a stack. By default, that stack comes from an anonymous mapping. Before Solaris 10, those mappings just appeared as \[ anon \] -- undifferentiated from other anonymous mappings; now we label them as thread stacks:

311992: ./mtpause.x86 2
08046000       8K rwx-- [ stack ]
08050000       4K r-x-- /home/ahl/src/tests/mtpause/mtpause.x86
08060000       4K rwx-- /home/ahl/src/tests/mtpause/mtpause.x86
C294D000       4K rwx-R    [ stack tid=3 ]
C2951000       4K rwxs- [ anon ]
C2A5D000       4K rwx-R    [ stack tid=2 ]
...

That can be pretty useful if you're trying to figure out what some address means in a debugger; before you could tell that it was from some anonymous mapping, but what the heck was that mapping all about? Now you can tell at a glance that its the stack for a particular thread.

Another kind of stack is the alternate signal stack. Alternate signal stacks let threads handle signals like SIGSEGV which might arise due to a stack overflow of the main stack (leaving no room on that stack for the signal handler). You can establish an alternate signal stack using the sigaltstack(2) interface. If you allocate the stack by creating an anonymous mapping using mmap(2) pmap(1) can now identify the per-thread alternate signal stacks:

...
FEBFA000       8K rwx-R    [ stack tid=8 ]
FEFFA000       8K rwx-R    [ stack tid=4 ]
FF200000      64K rw--- [ altstack tid=8 ]
FF220000      64K rw--- [ altstack tid=4 ]
...

core file content

Core files have always contained a partial snapshot of a process's memory mappings. Now that you can you manually adjust the content of a core file (see my previous entry) some ptools will give you warnings like this:
pargs: core 'core' has insufficient content
So what's in that core file? pmap(1) now let's you see that easily; mappings whose data is missing from the core file are marked with a \*:

$ coreadm -P heap+stack+data+anon
$ cat
^\Quit - core dumped
$ pmap core
core 'core' of 312077:  cat
08046000       8K rw--- [ stack ]
08050000       8K r-x--* /usr/bin/cat
08062000       4K rwx-- /usr/bin/cat
08063000      40K rwx-- [ heap ]
C2AB0000      64K rwx--
C2AD0000     752K r-x--* /lib/libc.so.1
C2B9C000      28K rwx-- /lib/libc.so.1
C2BA3000      16K rwx-- /lib/libc.so.1
C2BC0000     132K r-x--* /lib/ld.so.1
C2BF1000       4K rwx-- /lib/ld.so.1
C2BF2000       8K rwx-- /lib/ld.so.1
total      1064K

If you're looking at a core file from an earlier release or from a customer in the field, you can quickly tell if you're going to be able to get the data you need out of the core file or if the core file can only be interpreted on the original machine or whatever.