共有ライブラリが他の共有ライブラリに依存している場合、動的リンカが参照を確認できないのはなぜですか?

共有ライブラリが他の共有ライブラリに依存している場合、動的リンカが参照を確認できないのはなぜですか?

パスワード:

//a.c   I don't use header files as this is just for demo purpose.
extern void function_b(int num);
void function_a(int num) {
   function_b(num)
}
//b.c
void function_b(int num) {
   ...
}
//dll.c 
#include <dlfcn.h>
int main() {
   void *handle_a;
   void *handle_b;
   void (*pfunc_a)(int);
   ...
   handle_a = dlopen("./a.so", RTLD_LAZY);
   ...
   pfunc_a = dlsym(handle_a, "function_a");
   ...
   handle_b = dlopen("./b.so", RTLD_GLOBAL);
   ...
   pfunc_a(2020);
   ...
   return 0;
}

dll.c実行時に共有ライブラリをロードしようとすると、モジュールには参照がaあり、function_bモジュールbには定義がありますfunction_b。共有ライブラリを作成してプログラムが実行される前にディスクに存在しますが、プログラムを実行するとシンボル検索エラーが発生すると仮定しa.soますb.so

./a.so:undefined symbol: function_b

handle_a = dlopen("./a.so", RTLD_LAZY); ただし、ここで使用しているこのコード行を使用すると、RTLD_LAZYランタイムリンカーはシンボルを確認しようとせず、以前に呼び出すfunction_b機会を得ます。このように、動的リンカーはb.soの定義を使用して参照を変更します。dlopen("b.so", RTLD_GLOBAL)function_aa.sofunction_b

私の質問は次のとおりです

  • 私の理解は正しいですか?動的リンカーは、セクション内のfunction_bのコマンドアドレスに接続/再配置できるようにするか、.gotセクション.got.pltを変更する必要があります。a.so.textb.so

  • function_b私の理解が正しい場合、この場合、動的リンカーがまだ解決されないのはなぜですか?

ベストアンサー1

問題は、動的リンカーがを確認できないということではなく、function_b2番目の呼び出しがdlopen正しくないことです。あなた必要含めるRTLD_LAZYRTLD_NOW、他のフラグはこれら2つのフラグを補完します。

次の 2 つの値のいずれかを含める必要があります。バナー:

b.so負荷を次に変更してください。

handle_b = dlopen("./b.so", RTLD_NOW | RTLD_GLOBAL);

作業プログラムを生成します。

各呼び出しはロードされた最後のライブラリであるため。の間で選択するdlopen必要があります。上記で指定しましたが(遅延ローディングでは何も得られません)、この場合もうまく動作します。これに加えて、他のフラグを追加することもできます。実行時に見つけるためにシンボルをグローバルに使用できる必要があるためです。RTLD_LAZYRTLD_NOWb.soNOWLAZYRTLD_GLOBALb.sofunction_afunction_b

バラよりの例dlopen(3)実行する必要があるエラー処理dlopenなどの詳細で問題を明らかにします。

おすすめ記事