1

共有ライブラリでの dlopen() への失敗した呼び出しから未解決のすべてのシンボルを報告しようとしています。RTLD_LAZY と RTLD_NOW の両方を dlopen 呼び出しのフラグとして試しました。共有ライブラリに 10 個の不足しているシンボルがあることはわかっています (つまり、静的リンク g++ 何とか何とかを実行した場合: リンクは 10 個の不足しているシンボルで失敗します)。dlerror() を取得して、ロードの失敗時に失われた 10 個のシンボルすべてについて教えてもらいたいと考えています。

これを起こさせる方法を知っている人はいますか?man ページから、dlerror() が最後のエラーを返すことがわかります。だから多分私はあまりにも多くを求めていますが、誰かが知っているかどうか疑問に思いました.

本当にありがとう、

4

1 に答える 1

4

dlerror() を取得して、ロードの失敗時に失われた 10 個のシンボルすべてについて教えてもらいたいと考えています。

できません: ローダーは、ライブラリをロードできないことを発見するとすぐに (つまり、最初の見つからないシンボルを発見するとすぐに) エラーを報告します。ローダーがこれ以上先に進む意味はないので、そうしません。

ldd -rただし、 とを使用しLD_PRELOADLD_TRACE_LOADED_OBJECTS、完全な答えを得るために何が行われるかをシミュレートできます。例:

$ cat main.c
#include <dlfcn.h>
#include <stdio.h>

int main()
{
  void *p = dlopen("./foo.so", RTLD_NOW);
  if (p == NULL) {
    printf("%s\n", dlerror());
    return 1;
  }
  return 0;
}


$ cat foo.c
int bar(), baz();  // not defined anywhere
int foo() {
  return bar() + baz();
}

$ gcc main.c -ldl; gcc -fPIC -shared -o foo.so foo.c

$ ./a.out
./foo.so: undefined symbol: baz  # only the first symbol is reported

$ ldd -r ./a.out
    linux-vdso.so.1 =>  (0x00007fff52ddc000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f158e48d000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f158e0ce000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f158e6b2000)

あなたのプログラムは決して実行されず、ロードされないため、それは機能しませんfoo.so。しかしLD_PRELOAD、救助のために:

$ LD_BIND_NOW=1 LD_WARN=1 LD_TRACE_LOADED_OBJECTS=1 LD_PRELOAD=./foo.so ./a.out
    linux-vdso.so.1 =>  (0x00007fff3c1b6000)
    ./foo.so (0x00007ffd33212000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffd3300e000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffd32c4f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffd33414000)
undefined symbol: baz   (./foo.so)
undefined symbol: bar   (./foo.so)

ほら: すべての未解決のシンボルが報告されました。

于 2013-04-15T04:36:34.707 に答える