6

いくつかの前文

malloc、calloc、realloc、freeはすべてとで複製されているようld-linux.soですlibc.so。私が理解しているように、これは動的ローダーによって行われ、ロードされるld-linux.so前に内部のメモリ管理を処理libc.soし、そのメモリ管理機能を実行可能にします。ただし、これらの重複したシンボルについていくつか質問があります。

これは、mallocを呼び出して終了する非常に単純なCプログラムです。

#include <stdlib.h>

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

x86_64 linuxボックスでgccを使用してコンパイルし、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

libc.soおよびld.soのnmは、次のことを示しています。

$ 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

質問

  1. mallocはで複製されlibc.soますが、それが弱い記号であるld-linux.so場合は、両方が同じアドレスに解決される必要があります。ld-linux.soさらに、私が理解しているように、ダイナミックローダーのシンボル解決テーブルはグローバルであり、シンボルごとに1つのアドレスのみを解決します(間違っている場合は修正してください)。

    ただし、gdbはそれ以外のことを明確に示しています(2つの異なるアドレス)。何故ですか?

  2. gdbは、入力時に2つの異なるアドレスで効果的に中断しますbreak mallocが、入力時にld.soのシンボルの情報のみを表示しますinfo symbol malloc。何故ですか?

  3. 私はmallocでブレークし、独自libc.soのシンボルを定義していますが(nmで示されているように)、gdbはシンボルでブレークします。何故ですか?malloc__GI___libc_malloc

4

2 に答える 2

2
  1. GDBはmalloc、いわば「万が一に備えて」、検出できるすべてのシンボルにブレークポイントを設定しているのではないかと思います。GDBは、動的ローダーではなく、内部シンボルテーブルを使用します。このようにして、デバッグシンボルがある場合、エクスポートされていないシンボルでブレークする可能性があります。コマンドフィードバックには、一致が多すぎる場合のノイズを減らすために、おそらく1つのアドレスのみがリストされます。まだ「2つの場所」と記載されているので、で自分で調べることができますinfo breakpoints
  2. 私の推測では、info symbol実装者はこの状況を予測していなかったので、最初の一致だけを出力します
  3. __GI___libc_mallocmallocは、 libc.so内の内部の実際の実装の名前です。ソース行情報も取得するので"at malloc.c:2910"、ELFのsymtabからではなく、デバッグシンボルから取得されていると思います。繰り返しになりますが、1つの場所に多くの名前を付けることができるため(__libc_mallocシンボルリストを参照)、GDBは1つだけを選択します。

ところで、mallocld.soのGOTの'ポインタは、libc.soがロードされるときにlibcのアドレスに置き換えられmallocます(最初は内部実装を指します)。したがって、プロセスのエントリポイントに到達すると、両方で同じアドレスが取得され、ld.somallocは使用されなくなります。

于 2013-02-21T17:21:33.717 に答える
-1

ld.soはライブラリではなく、ダイナミックリンカです(プログラムの起動時に実行可能ファイルを共有ライブラリにリンクすることにより、メモリ内に実行可能イメージを作成するために暗黙的に呼び出されます)。

于 2013-02-14T03:35:20.073 に答える