2012-01-24 5 views
4

私の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.sob.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を習慣はありません。

+1

おそらく 'RTLD_DEEPBIND'があなたの問題の別の解決策であるかどうかチェックしましたか? – PlasmaHH

+0

@PlasmaHHそれは別のライブラリ(または他の関数)の関数を使用します。私はそこに解決策があるとは思わないが、それ以外の場合は –

+0

@VJovic:それは私のマンページ: "このスコープ内のシンボルのルックアップスコープをグローバルスコープの前に置く。これは、すでにロードされているライブラリに含まれている同じ名前のグローバルシンボルよりも、独自のシンボルを使用することを意味します。 – PlasmaHH

答えて

1

dlopenで重複するシンボルを検出して警告したいと思います。

私はdlopenとは思えません。

実行可能であっても、その問題を実行時に検出するのはおそらくです。です。あなたはビルド時に、その問題を検出する必要があり、ビルド後のステップとしてこれを行うに簡単です:あなたは任意の出力を取得する場合

nm -D your_plugin_dir/*.so | egrep ' [TD] ' | cut -d ' ' -f3 | 
    sort | uniq -c | grep -v ' 1 ' 

、あなたが重複したシンボルを持っている(一部重複したシンボルは、実際かもしれOK;「既知の良い」重複を除外する必要があります)。

+0

実際には、プラグインは他の共有オブジェクトを読み込み、重複したシンボルがそれらの中で発生することがあります。構造がかなり混乱していて、重複しているシンボルのためにすべての共有オブジェクトをチェックすることは望ましくありません。とにかくチップをありがとう。 –

関連する問題