Lorsque Linux charge des bibliothèques partagées, je crois savoir que la section de texte n'est chargée qu'une seule fois dans la mémoire physique et est ensuite mappée sur des tables de pages de différents processus qui la référencent. Où/qui assure/vérifie-t-il que la même section de texte de bibliothèque partagée n'a pas été chargée plusieurs fois dans une mémoire physique?Comment plusieurs copies de la section de texte de la bibliothèque partagée sont-elles évitées dans la mémoire physique?
La duplication est-elle évitée par le chargeur ou par l'appel système mmap() ou existe-t-il un autre moyen et comment?
Edit1: Je dois avoir montré ce qui a été fait jusqu'à présent (recherche). Ici, il est ...
Essayé de tracer une commande de sommeil simple.
$ strace sleep 100 &
[1] 22824
$ execve("/bin/sleep", ["sleep", "100"], [/* 26 vars */]) = 0
brk(0) = 0x89bd000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=92360, ...}) = 0
mmap2(NULL, 92360, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f56000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0`G\0004\0\0\0"..., 512) = 512
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f55000
fstat64(3, {st_mode=S_IFREG|0755, st_size=1706232, ...}) = 0
mmap2(0x460000, 1426884, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x460000
mmap2(0x5b7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x156) = 0x5b7000
mmap2(0x5ba000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x5ba000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f54000
...
munmap(0xb7f56000, 92360) = 0
...
Puis vérifié le fichier/proc/pid/maps pour ce processus;
$ cat /proc/22824/maps
00441000-0045c000 r-xp 00000000 fd:00 2622360 /lib/ld-2.5.so
...
00460000-005b7000 r-xp 00000000 fd:00 2622361 /lib/libc-2.5.so
...
00e3e000-00e3f000 r-xp 00e3e000 00:00 0 [vdso]
08048000-0807c000 r-xp 00000000 fd:00 5681559 /usr/bin/strace
...
Ici on a vu que l'argument addr pour mmap2() de libc.so.6 avec PROT_READ|PROT_EXEC
était à une adresse spécifique. Cela m'amène à croire que le mappage de la bibliothèque partagée dans la mémoire physique était en quelque sorte géré par le chargeur.
Le noyau Linux ainsi que tous les systèmes pertinents liés à cette question sont open-source, avec la source disponible pour la recherche. –
@Someprogrammerdude C'est vrai, mais tout le monde capable de vérifier cela dans le noyau, l'a appris il y a longtemps, alors que tout le monde peut être curieux, comment cela fonctionne-t-il? – peterh