6

Some preamble

It seems that malloc, calloc, realloc and free are all replicated in ld-linux.so and libc.so . As I understand it, that is done by the dynamic loader to take care of memory management within ld-linux.so before libc.so is loaded and makes its memory management functions aviable. However, I have some questions about those duplicated symbols:

Here's a very simple C program calling malloc and exiting:

#include <stdlib.h>

int main()
{
  void *p = malloc(8);
  return 0;
}

I compile it with gcc in an x86_64 linux box and make some debugging with gdb:

$ gcc -g -o main main.c
$ gdb ./main
(gdb) start
Temporary breakpoint 1 at 0x4004f8
Starting program: main 

Temporary breakpoint 1, 0x00000000004004f8 in main ()
(gdb) info symbol malloc
malloc in section .text of /lib64/ld-linux-x86-64.so.2
(gdb) b malloc
Breakpoint 2 at 0x7ffff7df0930: malloc. (2 locations)
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   <MULTIPLE>         
2.1                         y     0x00007ffff7df0930 in malloc at dl-minimal.c:95
2.2                         y     0x00007ffff7a9f9d0 in __GI___libc_malloc at malloc.c:2910

nm in libc.so and ld.so reveals the following:

$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep malloc
00000000000829d0 T __libc_malloc
00000000003b6700 V __malloc_hook
00000000003b8b00 V __malloc_initialize_hook
00000000000829d0 T malloc
0000000000082db0 W malloc_get_state
00000000000847c0 T malloc_info
0000000000082480 W malloc_set_state
00000000000844f0 W malloc_stats
0000000000084160 W malloc_trim
00000000000844b0 W malloc_usable_size

$ nm -D /lib64/ld-linux-x86-64.so.2 | grep malloc
0000000000016930 W malloc

Questions

  1. malloc is replicated in libc.so and ld-linux.so but in the case of ld-linux.so it is a weak symbol, so they should both resolve to the same address. Additionally, as I understand it, the dynamic loader's symbol resolution table is global and resolves only one address per symbol (correct me if I'm wrong).

    However, gdb clearly shows otherwise (two different addresses). Why is that?

  2. gdb effectively breaks at two different addresses when typing break malloc but only shows information of a symbol in ld.so when typing info symbol malloc. Why is that?

  3. Although I am breaking at malloc and libc.so defines a malloc symbol of its own (as shown by nm), gdb breaks at symbol __GI___libc_malloc . Why is that?

4

2 回答 2

2
  1. 我怀疑 GDB 只是在它可以找到的所有符号上放置断点malloc,“以防万一”可以这么说。GDB 使用它的内部符号表,而不是动态加载器的。这样,如果您有调试符号,它可以在未导出的符号上中断。命令反馈只列出一个地址,可能是为了在匹配太多的情况下减少噪音。它仍然提到“2 个位置”,因此您可以自己检查它info breakpoints
  2. 我的猜测是info symbol实施者只是没有预见到这种情况,所以它只打印第一场比赛
  3. __GI___libc_mallocmalloclibc.so内部的实际实现的名称。由于您还获得了 source line info "at malloc.c:2910",我猜它来自调试符号,而不是来自 ELF 的符号表。同样,一个位置可以有多个名称(参见__libc_malloc符号列表),因此 GDB 只选择一个。

顺便说一句,当 libc.so 被加载时malloc,ld.so 的 GOT 中的 ' 指针确实被 libc 的malloc地址替换(最初它指向内部实现)。因此,当到达进程入口点时,您确实会获得相同的地址,并且malloc不再使用 ld.so 的地址。

于 2013-02-21T17:21:33.717 回答
-1

ld.so不是库,它是动态链接器(通过在程序启动时将可执行文件与共享库链接,隐式调用以在内存中创建可运行映像)。

于 2013-02-14T03:35:20.073 回答