共享库如何由不同的进程共享?

时间:2010-10-26 09:03:22

标签: linux linux-kernel

我阅读了一些与-fPIC参数共享库的文档, .so的.text seqment将在process fork的动态链接阶段共享 (例如,该过程将.so映射到相同的物理地址)

我感兴趣的是谁(内核或ld.so)以及如何实现这一目标? 也许我应该追踪代码,但我不知道从哪里开始。

然而,我试图验证声明 我决定检查函数地址,就像libc.so中的printf一样,所有c程序都将链接。 我得到进程的printf虚拟地址,需要获取物理地址。试图写一个内核模块并将地址值传递给内核,然后调用virt_to_phys。但它没有用,因为virt_to_phys仅适用于kmalloc地址。

因此,进程页表查找可能是查找虚拟地址映射到物理地址的解决方案。是否有任何方法可以进行页面表查看?或者其他方式可以适合验证实验?

提前感谢!

2 个答案:

答案 0 :(得分:4)

动态加载程序使用mmap(2)和MAP_PRIVATE以及适当的权限。您可以通过从strace -e file,mmap运行命令来查看它的确切功能。例如:

strace -e file,mmap ls 

所有的魔力来自mmap(2)mmap(2)在调用进程中创建映射,它们通常由文件或交换(匿名映射)支持。在文件支持的映射中,MAP_PRIVATE意味着对内存的写入不会更新文件,并导致该页面由该点上的交换支持(写时复制)。

动态加载程序从ELF的程序头中获取所需的信息,您可以使用以下命令查看:

readelf -l libfoo.so

从这些中,动态加载器确定要映射的内容为代码,只读数据,数据和bss(文件中零大小的零填充段,内存中的非零大小,以及仅通过隐藏性来匹配的名称Lisp的车和司机。

因此,事实上,代码以及数据是共享的,直到写入导致写时复制。这就是为什么将常数数据标记为常数是一个潜在的重要空间优化(参见DSO howto)。

您可以在mmap(2)联机帮助页和Documentation/nommu-mmap.txt中获取更多信息(MMU案例中,无MMU适用于嵌入式设备,如ADSL路由器和Nintendo DS)。

答案 1 :(得分:2)

共享库只是映射文件的特定用途。

文件在进程的地址空间中映射的地址与是否共享无关。

即使页面映射到不同的地址,也可以共享页面。

要确定是否共享页面,请执行以下操作:

  1. 通过检查/ proc / pid / maps
  2. 找到文件映射到的地址
  3. 有一个从/ proc / pid / pagemap中提取数据的工具 - 找到并使用它。这将为您提供有关映射的确切页面以及它们在哪个物理位置的信息
  4. 如果两个进程的页面映射在同一个物理地址,那么它当然是共享的。