El significado de la salida de pmap


12

Escribí main.cen Linux:

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

Cuando lo compilo y lo inicio, puedo pmaphacerlo:

# 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

total (3876) dividido por K es igual a la VIRTcolumna en la salida de top. Ahora, ¿dónde está el segmento de texto? En 400000, 600000 y 601000, ¿verdad? ¿Dónde puedo leer una explicación de qué es dónde? man pmapno ayudó.


los segmentos de texto son en realidad de solo lectura, por lo que está en 0000000000600000.
Danila Ladner

¡Gracias! ¿No debería ser el segmento de texto ejecutable también?
Thorsten Staerk

1
Sí, tiene usted razón. r y rx. 0000000000400000 también.
Danila Ladner

Respuestas:


14

El segmento de texto es el mapeo en 0x400000 - está marcado 'rx' para legible y ejecutable. La asignación en 0x600000 es de solo lectura, por lo que es casi seguro la sección ".rodata" del archivo ejecutable. GCC coloca literales de cadena C en una sección de solo lectura. La asignación en 0x601000 es 'rw-', por lo que probablemente sea el famoso montón. Puede tener sus malloc()1024 bytes ejecutables e imprimir la dirección para ver con seguridad.

Puede obtener un poco más de información al encontrar el PID de su proceso y hacer lo siguiente: cat /proc/$PID/maps- en mi computadora portátil Arch, eso brinda información adicional. Está ejecutando un kernel 3.12, por lo que también lo tiene /proc/$PID/numa_maps, y una captura que también puede dar una pequeña idea.

Otras cosas para ejecutar en el archivo ejecutable: nmy objdump -x. El primero puede darle una idea de dónde se encuentran varias cosas en el mapa de memoria, para que pueda ver qué hay en la sección 0x4000000 frente a las otras secciones. objdump -xmuestra encabezados de archivos ELF entre muchas otras cosas, para que pueda ver todas las secciones, completas con los nombres de las secciones y si están asignadas en tiempo de ejecución o no.

En cuanto a encontrar una explicación por escrito de "qué es dónde", tendrá que hacer cosas como google para "diseño de memoria ELF FILE". Tenga en cuenta que el formato de archivo ELF puede admitir diseños de memoria más exóticos que los que se usan habitualmente. GCC y Gnu ld y glibc hacen suposiciones simplificadoras sobre cómo un archivo ejecutable se presenta y luego se asigna a la memoria en tiempo de ejecución. Existen muchas páginas web que pretenden documentar esto, pero solo se aplican a versiones anteriores de Linux, versiones anteriores de GCC o glibc, o solo se aplican a ejecutables x86. Si no lo tiene, obtenga el readelfcomando. Si puede escribir programas en C, cree su propia versión objdump -xo readelffamiliarícese con el funcionamiento de los archivos ejecutables y su contenido.


2
Gran respuesta. Ahora, ¿dónde está el montón del programa? ¿Y qué significa esto [anon]? ¿Qué tengo que buscar en Google para descubrir esto?
Thorsten Staerk

1
¿Sabes que? Me equivoqué sobre el mapeo de direcciones 0x601000, ese es el montón, probablemente. Tendrás que usarlo readelfo objdumpdescifrarlo, y sea cual sea el ejecutable que hayas hecho. My Arch linux box usa /usr/lib/libc-2.18.so, por lo que es bastante diferente a su caja.
Bruce Ediger

2
0x601000es el segmento de datos Contiene .data, .bssy se puede ampliar a través de brk(). [anon]indica memoria sin respaldo de archivo (respaldada por intercambio), obtenida a través de mmap(). dlmalloc utiliza brk()para asignaciones menores a ~ 64Kb IIRC, y mmap()para asignaciones más grandes. El montón es todo lo asignado por malloc, tanto la parte extendida del segmento de datos como las mmap()asignaciones basadas.
ninjalj
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.