5

When looking at the memory maps in /proc/pid/maps, we can see different length addresses:

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

We have addresses with 8 digit lengths like:

  • 00400000-0042e000

And ones with 12 digit lengths (the last 3 digits are always 0):

  • 7f8313e5c000-7f8314109000

Why are those addresses formatted this way, and can I convert them to 8 digit lengths?

9

First, you can not convert the addresses to have just 8 digits. Memory addresses can and will have much larger values than could be represented with just 8 digits.

The reason why memory addresses are represented in /proc/pid/maps as they are is on the line 283 in fs/proc/task_mmu.c (or task_nommu.c) in a recent kernel source tree:

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);

What this boils down to is that in any memory address which has a hex string representation shorter than 8 digits, will get padded with leading zeros. Any value larger than that will be represented as it is, not truncated to 8 digits. That's just the way how printk()'s printf-style formatting works.

Now what to make out of all this? Probably you should take a minute to think about why would you want to truncate memory addresses to 8 digits. What do you think is the benefit of doing so?

  • 2
    Additionally, it's worth mentioning that the trailing zeroes come off since memory isn't allocated byte-wise but you can only be allocated by whole pages, which (on x86_64) are usually 4kiB (thus the last three hex digits will always be 000, but significant). – Andreas Wiese Apr 26 '14 at 20:02
3

These addresses are as they should be and you shouldn't think of them as being something you can truncate. Take a look at the man page man proc and read about the contents of the file /proc/<pid>/maps for more on what these columns mean.

excerpt

   /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

The addresses are being displayed this way because there are leading zeros that are not being shown in this output. You can use this rough awk command that I've constructed which will put the proper leading zeros back into the output so that everything shows up lined up with the full amount of address space taken into account with respect to the addresses.

$ 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

Example

Here's a sample maps file from my system.

before

$ 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]

after

$ 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]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.