/ proc / pid / maps endereços (e convertê-los)

5

Ao olhar para os mapas de memória em / proc / pid / maps, podemos ver diferentes endereços de tamanho:

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

Temos endereços com comprimentos de 8 dígitos, como:

  • 00400000-0042e000

E aqueles com comprimentos de 12 dígitos (os últimos 3 dígitos são sempre 0):

  • 7f8313e5c000-7f8314109000

Por que esses endereços são formatados dessa forma e posso convertê-los para comprimentos de 8 dígitos?

    
por pnohmphen2 26.04.2014 / 19:56

2 respostas

9

Primeiro, você não pode converter os endereços para ter apenas 8 dígitos. Os endereços de memória podem e terão valores muito maiores do que poderiam ser representados com apenas 8 dígitos.

A razão pela qual os endereços de memória são representados em /proc/pid/maps , como eles estão, está na linha 283 em fs/proc/task_mmu.c (ou task_nommu.c ) em uma árvore de código-fonte recente do kernel:

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

O que isto significa é que em qualquer endereço de memória que tenha uma representação de cadeia hexadecimal menor que 8 dígitos, será preenchido com zeros à esquerda. Qualquer valor maior que esse será representado como está, não truncado para 8 dígitos. É assim que funciona a formatação no estilo printf de printk() .

Agora, o que fazer com tudo isso? Provavelmente você deve levar um minuto para pensar em por que você deseja truncar endereços de memória para 8 dígitos. O que você acha que é o benefício de fazer isso?

    
por 26.04.2014 / 21:39
3

Esses endereços são como deveriam e você não deve pensar neles como algo que você pode truncar. Dê uma olhada na página manual man proc e leia sobre o conteúdo do arquivo /proc/<pid>/maps para saber mais sobre o significado dessas colunas.

trecho

   /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

Os endereços estão sendo exibidos dessa maneira porque há zeros à esquerda que não estão sendo mostrados nessa saída. Você pode usar este comando áspero awk que eu construí que colocará os zeros iniciais apropriados de volta na saída para que tudo apareça alinhado com a quantidade total de espaço de endereço considerado em relação aos endereços.

$ 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

Exemplo

Aqui está um exemplo de arquivo de mapas do meu sistema.

antes

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

depois

$ 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]
    
por 28.04.2014 / 06:45