Linuxが共有ライブラリを読み込むとき、私の理解では、テキストセクションは物理メモリに一度だけロードされ、それを参照する別のプロセスのページテーブルにマップされます。共有ライブラリテキストセクションの複数のコピーは、どのようにして物理メモリ内で回避されますか?
しかし、/ whoは、同じ共有ライブラリのテキストセクションが物理メモリに複数回ロードされていないことを確認/確認します。
ローダやmmap()システムコールによって重複が回避されるのでしょうか、それとも他の方法や方法がありますか?
Edit1: これまでに行われたこと(研究)を示しているに違いありません。ここにあります...
シンプルスリープコマンドをトレースしようとしました。
$ 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
...
このプロセスの/ proc/pid/mapsファイルを確認してください。
$ 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
...
は、ここでは、
PROT_READ|PROT_EXEC
とlibc.so.6とのmmap2ためaddr引数は()特定のアドレスにあったことが分かりました。これにより、物理メモリ内の共有ライブラリマッピングがローダーによって何らかの形で管理されていると私は考えていました。
この質問に関連するすべての関連システムと同様に、Linuxカーネルは、ソースが閲覧可能なオープンソースです。 –
@Someprogrammerdudeそれは本当ですが、カーネルでこれをチェックすることができる人は、ずっと前にそれを学んだことがあります。 – peterh