0

共有ライブラリが不良です(未定義のシンボル)。

初めてdlopen()を呼び出すと、dlerror()から正しいエラーメッセージが表示されたNULLの結果が得られます。

エラーメッセージを無視し、同じ引数を使用してdlopen()を呼び出すと、2回目にnull以外のハンドルが取得されます(これは、ライブラリが正常にロードされたことを示します)。これは明らかに間違っています。

この問題はUbuntu11.04で発生します(IIRC、10.10にはこの問題はありませんでした)。Centos5.5ではこの問題は発生しません。

特に、この問題はTclインタープリター内で発生します。最初に正規化された絶対パスを使用して共有ライブラリをロードしようとします。それが失敗した場合は、ユーザーが指定した正確なパス文字列を使用して文字通り再び失敗します。私の場合、両方とも失敗するはずですが、Ubuntu11.04では2番目の呼び出しが正しく成功していません。

奇妙なことに、この問題を再現できるのは、正確な本番共有ライブラリを使用した場合のみです。縮小された共有ライブラリを作成すると、正しく機能しています。

このようなプログラムは、私の本番ライブラリの問題を示すのに十分です。

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

int main()
{
  void* h;

  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
  printf("err is %s\n", dlerror());
  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
}
4

1 に答える 1

0

私はしばらくの間この問題の端を見てきましたが、それを引き起こした原因を正確に特定することはまだできていません(Googleにとって正しいものをまだ見つけていませんが、Ubuntuが感じているものではありません見出しが変更されたため、見つけるのが困難です)。誰かがIRCを渡す際に何が悪いのかを教えてくれましたが、それは少し前のことでした。当時、私は別の問題に目が離せず、(書き留めた、またはメモリに)十分な情報を保存できませんでした。それを再構築します。これが私の最高の思い出です…</p>

私の知る限り、いくつかのライブラリを構築するときに使用されるリンクオプション、または依存ライブラリを解決するときに使用されるデフォルトオプションにいくつかの変更があり、これによりTclは依存するすべてのものをロードできなくなります。一部の依存関係(または依存関係の依存関係)のロードに失敗するため、ライブラリの残りの部分のロードに失敗し(RTLD_NOW必要なフラグのため)、現在の場所に到達します。リンク時のオプションを変更するなどして簡単に修正できますが、何が悪いのか詳しくはわかりません。

要するに、それは誰かのバグですが、私にはわかりません。多くの(すべてではありませんが!)Linuxディストリビューターは、発見または作成した問題についてアップストリームにフィードバックするのがあまり得意ではありません。

注意:上記のコードがTclのloadコマンドのプロキシである場合、これはそれ自体がトリッキーな領域であることに注意してください。

于 2011-07-06T13:31:02.620 に答える