共享库函数未加载到相同的内存位置

时间:2014-02-03 12:17:09

标签: c linux operating-system shared-libraries shared-memory

我使用OPenSSL共享库编写了一个程序并制作了另一个副本(Program2是program1的副本)。只是为了检查共享库函数是否只加载一次,我从Program1和program2打印地址。令我惊讶的是,我有时会得到相同的地址,但在其他时间我得到了不同的地址。

根据我的理解,共享库函数加载到共享内存中,只加载一个副本。为什么我得到两个不同的地址,表示共享功能被加载到两个不同的内存位置。

以下代码我在获取相同地址时使用

案例1: 计划1:

#include <openssl/aes.h>

int main(int argc, char ** argv)
{
printf("Address of AES_cbc_encrypt =%p\n",&AES_cbc_encrypt);

while(1) {} 

......

}

AES_cbc_encrypt的地址= 0x400600

计划2:

   #include <openssl/aes.h>

    int main(int argc, char ** argv)
    {
    printf("Address of AES_cbc_encrypt =%p\n",&AES_cbc_encrypt);

    while(1) {} 

    ......

    }

AES_cbc_encrypt的地址= 0x400600

CASE2:当我为共享库函数获取两个不同的地址时

计划1:

 #include <openssl/aes.h>

    int main(int argc, char ** argv)
    {
    printf("Address of AES_cbc_encrypt =%p\n",&AES_cbc_encrypt);

    while(1) {} 

    ......

    }

AES_cbc_encrypt的地址= 0x400840

计划2:

   #include <openssl/aes.h>

    int main(int argc, char ** argv)
    {
    printf("Address of AES_cbc_encrypt =%p\n",&AES_cbc_encrypt);

// open function makes the difference  
fd = open(argv[1], O_RDONLY);

    if (fd <= 0)
    {
        strerror(errno);
        exit(0);
    }

    while(1) {} 

    ......

    }

AES_cbc_encrypt的地址= 0x4007f0

在案例2中,我没有获得共享库函数的相同地址。是什么原因 ?如何确保将共享库函数加载到相同的内存位置。

我在Fedora 19下使用GCC。

编辑1:

根据Paul和John的评论/回答,上述地址不是物理地址,它们是虚拟地址。所以我尝试将虚拟地址转换为物理地址(我使用此工具的代码Capturing Process Memory Usage Under Linux)来检查它们是否相同,但我得到两个不同的物理地址。 我做错了吗?还有其他方法可以将强制将共享库加载到同一个物理内存中。

提前致谢。

1 个答案:

答案 0 :(得分:1)

您的操作系统会为您解决此问题,您无需担心。但是,如果您仍然担心它,请查阅top中的“SHR”(共享)列以查看进程之间共享的内存量。

还要考虑“虚拟内存”(做一个网络搜索)意味着仅仅因为两个不同的进程使用两个不同的值指针来引用某些东西,并不意味着操作系统不能只将它们映射到幕后相同的后备存储。事实上,通常会发生这样的事情:操作系统将加载共享库一次,并在两个进程中将它映射到两个不同的基地址,并且没有功能上的区别,只要您实际上并不关心这些虚拟地址值(你不应该)。