J'ai écrit main.c
sous Linux:
int main()
{
while (1){}
}
Quand je le compile et le démarre, je le peux pmap
:
# 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) divisé par K est égal à la VIRT
colonne dans la sortie de top
. Maintenant, où est le segment de texte? À 400000, 600000 et 601000, non? Où puis-je lire une explication, où est-il? man pmap
n'a pas aidé.
linux
process
memory
virtual-memory
Thorsten Staerk
la source
la source
Réponses:
Le segment de texte est le mappage à 0x400000 - il est marqué «rx» pour lisible et exécutable. Le mappage à 0x600000 est en lecture seule, c'est donc presque certainement la section ".rodata" du fichier exécutable. GCC place les littéraux de chaîne C dans une section en lecture seule. Le mappage à 0x601000 est 'rw-', donc c'est probablement le fameux tas. Vous pourriez avoir votre
malloc()
1024 octets exécutable et imprimer l'adresse pour voir avec certitude.Vous pourriez obtenir un peu plus d'informations en trouvant le PID de votre processus et en faisant:
cat /proc/$PID/maps
- sur mon ordinateur portable Arch, cela donne des informations supplémentaires. Il exécute un noyau 3.12, donc il en a aussi/proc/$PID/numa_maps
, et un catting qui pourrait aussi donner un petit aperçu.Autres choses à exécuter sur le fichier exécutable:
nm
etobjdump -x
. Le premier peut vous donner une idée de l'emplacement de diverses choses dans la carte mémoire, vous pouvez donc voir ce qui se trouve dans la section 0x4000000 par rapport aux autres sections.objdump -x
vous montre les en-têtes de fichiers ELF parmi beaucoup d'autres choses, afin que vous puissiez voir toutes les sections, complètes avec les noms de section et si elles sont mappées lors de l'exécution ou non.Pour ce qui est de trouver une explication écrite de "où est-il", vous devrez faire des choses comme google pour "la disposition de la mémoire du fichier ELF". Sachez que le format de fichier ELF peut prendre en charge des dispositions de mémoire plus exotiques que celles couramment utilisées. GCC et Gnu ld et glibc font tous des hypothèses simplificatrices sur la façon dont un fichier exécutable est disposé puis mappé en mémoire au moment de l'exécution. Il existe de nombreuses pages Web qui prétendent documenter cela, mais ne s'appliquent qu'aux anciennes versions de Linux, aux anciennes versions de GCC ou de la glibc, ou ne s'appliquent qu'aux exécutables x86. Si vous ne l'avez pas, obtenez la
readelf
commande. Si vous pouvez écrire des programmes C, créez votre propre version deobjdump -x
oureadelf
pour vous familiariser avec le fonctionnement des fichiers exécutables et leur contenu.la source
readelf
ouobjdump
pour le comprendre, et quel que soit l'exécutable que vous avez créé. Ma boîte Linux Arch utilise /usr/lib/libc-2.18.so, donc c'est assez différent de votre boîte.0x601000
est le segment de données. Il contient.data
,.bss
et peut être étendue viabrk()
.[anon]
indique la mémoire non sauvegardée par les fichiers (donc sauvegardée par swap), obtenue viammap()
. dlmalloc utilisebrk()
pour des allocations inférieures à ~ 64 Ko IIRC etmmap()
pour des allocations plus importantes. Le tas est tout ce qui est alloué par malloc, à la fois la partie étendue du segment de données et lesmmap()
allocations basées sur.