为什么共享库(.so 文件)加载为私有?

Why are shared libraries (.so files) loaded as private?

这来自 smaps 文件:
b750d000-b76bc000 r-xp 00000000 08:01 918842 /lib/i386-linux-gnu/libc-2.23.so
我相信 r-xp 中的 p 表示它是作为私有加载的。为什么会这样?如果将每个 .so 文件的副本加载到不同进程的不同内存地址,这不会破坏共享库的目的吗?这种私人加载有什么好处?

p对应MAP_PRIVATEman mmap 声称:

MAP_PRIVATE: Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. [...]

只要不进行任何修改,此 VMA 的物理内存页面将由所有进程共享 (它们也与内核缓存共享)。当在给定进程中修改虚拟页面时,该进程将复制(取消共享)该页面(写时复制)。

我们来看看:

$ cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:11 529223                             /bin/cat
0060b000-0060c000 r--p 0000b000 08:11 529223                             /bin/cat
0060c000-0060d000 rw-p 0000c000 08:11 529223                             /bin/cat
[...]
  • 第一个和第二个 VMA 是只读的。它们(通常)不会被修改,并且(通常)会被所有进程共享。

  • 第三个 VMA (rw-p) 是可写的,但一个进程中的修改必须对其他进程不可见。此 VMA 包含不同进程不共享的(可变)全局变量。