私のLinuxアプリケーションでは、dlopen
でプラグインアーキテクチャを使用しています。共有オブジェクトがdlopenで重複するシンボルを検出する
のdlopenでオープンされている(パス、RTLD_GLOBAL | RTLD_LAZY)プラグインは、共通のRTTI情報にアクセスする必要があるため、 `
オプションRTLD_GLOBAL
が必要です。 Ocaisionallyいくつかのプラグインが同じシンボルをエクスポートすることが起こります。これは通常は起こらないはずですが、それが発生するとランダムなセグメンテーションが発生し、デバッグが難しくなります。だから私はdlopenで重複したシンボルを検出し、それらについて警告したいと思います。
これを行う方法はありますか?
これを説明する簡単な例を示します。主実行可能ファイルのコードが
#include <string>
#include <dlfcn.h>
#include <iostream>
#include <cassert>
typedef void (*Function)();
void open(const std::string& soname)
{
void* so = dlopen(soname.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!so) {
std::cout << dlerror() << std::endl;
} else {
Function function = reinterpret_cast<Function>(dlsym(so, "f"));
assert(function);
function();
}
}
int main()
{
open("./a.so");
open("./b.so");
return 0;
}
であり、これはg++ main.cpp -o main -ldl
a.so
とb.so
により
#include <iostream>
void g()
{
std::cout << "a.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
と
#include <iostream>
void g()
{
std::cout << "b.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
から構築されているコマンドによって構築されていますコマンドg++ -fPIC a.cpp -share -o a.so
とそれぞれg++ -fPIC b.cpp -share -o b.so
である。今、私は./main
を実行する場合、私は私が
a.cpp
b.cpp
取得RTLD_LOCAL
で
a.cpp
a.cpp
を取得するが、私が説明したように私はRTLD_LOCAL
を習慣はありません。
おそらく 'RTLD_DEEPBIND'があなたの問題の別の解決策であるかどうかチェックしましたか? – PlasmaHH
@PlasmaHHそれは別のライブラリ(または他の関数)の関数を使用します。私はそこに解決策があるとは思わないが、それ以外の場合は –
@VJovic:それは私のマンページ: "このスコープ内のシンボルのルックアップスコープをグローバルスコープの前に置く。これは、すでにロードされているライブラリに含まれている同じ名前のグローバルシンボルよりも、独自のシンボルを使用することを意味します。 – PlasmaHH