共享库函数针对不同进程加载在不同物理地址
Function of shared library is loaded at different physical addresses for different processes
我在两个程序中得到libc.so中函数"printf"的物理地址,两个物理地址不同。而且我读取了两个不同的物理地址,内容都是almost一样的。这意味着函数 "printf" 在内存中有两个副本?
详情:
我的os是32位的linux。
读“/proc/self/pagemap”计算物理地址.
物理地址读取是用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 @0xf7e5add0
在 libc.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
我在两个程序中得到libc.so中函数"printf"的物理地址,两个物理地址不同。而且我读取了两个不同的物理地址,内容都是almost一样的。这意味着函数 "printf" 在内存中有两个副本?
详情:
我的os是32位的linux。
读“/proc/self/pagemap”计算物理地址.
物理地址读取是用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 @0xf7e5add0
在 libc.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