Escribí main.c
en Linux:
int main()
{
while (1){}
}
Cuando lo compilo y lo inicio, puedo pmap
hacerlo:
# 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 VIRT
columna 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 pmap
no ayudó.
linux
process
memory
virtual-memory
Thorsten Staerk
fuente
fuente
Respuestas:
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:
nm
yobjdump -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 -x
muestra 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
readelf
comando. Si puede escribir programas en C, cree su propia versiónobjdump -x
oreadelf
familiarícese con el funcionamiento de los archivos ejecutables y su contenido.fuente
readelf
oobjdump
descifrarlo, 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.0x601000
es el segmento de datos Contiene.data
,.bss
y se puede ampliar a través debrk()
.[anon]
indica memoria sin respaldo de archivo (respaldada por intercambio), obtenida a través demmap()
. dlmalloc utilizabrk()
para asignaciones menores a ~ 64Kb IIRC, ymmap()
para asignaciones más grandes. El montón es todo lo asignado por malloc, tanto la parte extendida del segmento de datos como lasmmap()
asignaciones basadas.