共享库函数针对不同进程加载在不同物理地址

Function of shared library is loaded at different physical addresses for different processes

我在两个程序中得到libc.so中函数"printf"的物理地址,两个物理地址不同。而且我读取了两个不同的物理地址,内容都是almost一样的。这意味着函数 "printf" 在内存中有两个副本?

详情:

  1. 我的os是32位的linux。

  2. 读“/proc/self/pagemap”计算物理地址.

  3. 物理地址读取是用fmem模块实现的,whos源码在git@github.com:NateBrune/fmem.git

I get physical addresses of function "printf" in libc.so in two programs, and two physical addresses are different.

你可能做错了(但很难猜:你没有提供任何细节)。

特别注意以下程序:

#include <stdio.h>

int main()
{
  printf("&printf: %p\n", &printf);
  return 0;
}

does not print printf in libc.so.6 的实际地址,正如可以用 GDB 观察到的那样:

(gdb) start
Temporary breakpoint 1 at 0x8048426: file pagemap.c, line 5.
Starting program: /tmp/pagemap

Temporary breakpoint 1, main () at pagemap.c:5
5     printf("&printf: %p\n", &printf);
(gdb) n
&printf: 0x80482f0
6     return 0;

(gdb) info symbol 0x80482f0
printf@plt in section .plt of /tmp/pagemap

(gdb) p &printf
 = (<text variable, no debug info> *) 0xf7e5add0 <printf>

(gdb) info sym 0xf7e5add0
printf in section .text of /lib32/libc.so.6

请注意 printf @0x80482f0 在主可执行文件中,并且 不是 应该共享(除了在同一可执行文件 运行 的多个实例之间同时),并且 不是 printf 的代码实际所在的位置。

printf @0xf7e5add0libc.so.6 中,printf 的代码实际所在的位置。 那个页面应该由使用libc.so.6的所有进程共享。

P.S。要在 libc.so.6 中获取 printf 实际 地址,可以改用此程序:

#include <stdio.h>
#include <dlfcn.h>

int main()
{
  printf("&printf: %p\n", &printf);
  printf("&printf: %p\n", dlsym(RTLD_NEXT, "printf"));
  return 0;
}

gcc -g pagemap.c -o pagemap -m32 -ldl -D_GNU_SOURCE

(gdb) run
Starting program: /tmp/pagemap
&printf: 0x80483c0
&printf: 0xf7e55dd0

(gdb) info sym 0xf7e55dd0
printf in section .text of /lib32/libc.so.6