2017-03-23 8 views
1

私は実行可能なライブラリと動的にリンクされたライブラリで構成されている埋め込みLinux C++アプリケーションに問題があります。実行可能ファイルは、ライブラリのエントリポイントの1つである関数を呼び出しますが、その関数は正しく動作しません。私はgdbを使って調査し、ライブラリ内の別の関数xyz()を呼び出すはずのライブラリ関数が、実際には実行可能ファイル内で同じ名前の関数xyz()を呼び出していることがわかります。Linuxライブラリは、実行可能ファイルであいまいな名前の関数を呼び出します - これは可能ですか?

私はこれが起こる可能性が非常に驚いているので、私は何か愚かなことをしています。実行可能ファイルを参照せずに、ライブラリ自体にリンクされていませんか?実行可能ファイル内のabc()の代わりに実行ファイルが誤ってライブラリ内のabc()を呼び出した場合、少なくともライブラリにリンクされているため、実行時には少し意味がありますが、リンカがそのデュアル定義?または、ローカル関数の優先順位をつけますか?

私の関数の名前を変更して名前が一致しないようにすることができましたが、何が起こっているのかを理解したいと思います。私はこの分野やgccツールで多くの経験がありません。まず、上記のシナリオで起こっていると思いますか?

実行ファイルとライブラリの両方が別のライブラリを呼び出します。 私が使用しているライブラリのlinkコマンドは、

powerpc-unknown-linux-gnuspe-g ++ - 4.9.3 aaa.o bbb.o [etc] -shared -o libmylibary.so -L ..です。/otherlibpath -Wl、-rpath-link、../otherlibpath -lotherlibname

+0

実行ファイルのリンクコマンドはどうですか? '-rdynamic'を使用していますか? –

+0

@ WumpusQ.Wumbley:-rdynamicは使用しません。これは、-Wl、-rpath-link、../otherlibpath -lotherlibname -Wl、-Bstatic -lxxx -Wl、-Bdynamic -lmylibraryここで、lxxxは静的にリンクされているライブラリで、otherlibは両方ともリンクされている動的ライブラリです私が上記のことに。あなたの質問をありがとう。 – Spalteer

答えて

1

これはダイナミックリンカーの仕組みです。実行可能なシンボルは、動的ライブラリのシンボルより優先度が高くなります。ダイナミックライブラリの設計者はそれについて認識している必要があります。彼女は、望ましくない記号の不一致を避けるために対策を講じなければならない。ほとんどのライブラリは次のものを使用します。

  • C++の場合、名前空間を使用します。ライブラリからエクスポートされたすべてのシンボルは、ライブラリの名前空間になければなりません。
  • Cの場合、エクスポートされたすべてのシンボルに名前接頭辞または接尾辞を使用します。たとえば、OpenSSLライブラリは接頭語SSL_を使用し、公開関数の名前はSSL_set_mode()なので、不要なシンボルの衝突は回避されます。
  • プライベートであると思われるシンボルをライブラリからエクスポートしないでください。シンボルがライブラリからエクスポートされていない場合、ダイナミックリンカはライブラリ内のローカルシンボルを使用します。 #pragma visibilityはあなたの友人です。重複したシンボルとライブラリがサードパーティのライブラリであり、その著者は、あなたがあなたの関数の名前を変更するか、おそらくライブラリの更新のために、著者に依頼する必要があり、その後上記の勧告に従わない場合はhttps://gcc.gnu.org/wiki/Visibility

を参照してください。上記のリンクで

void exported_function1(int); 
void exported_function2(int); 
#pragma GCC visibility push(hidden) 
void private_function1(int); 
void private_function2(int); 
#pragma GCC visibility pop 

詳細:

EDIT

エクスポート/エクスポートは#pragma visibilityディレクティブ(gccの特定の拡張子)によって制御されてもよいしません。

+0

実行可能シンボルのエクスポートを禁止するにはどうすればよいですか?それは(nm -Dまたはreadelf --dyn-symsで見て)それらのすべてをエクスポートするようですが、実行可能ファイルは通常はエクスポートするつもりはないと思っていたでしょう。 – Spalteer

+0

さらに実験したところ、実行可能ファイルによってエクスポートされるのは、それがリンクされている動的ライブラリ内の関数名に一致するものだけです。それを止めるために、私は実行可能ファイルのコンパイルとリンクコマンドに-fvisibility = hiddenを追加しました。だから問題は解決される。ライブラリは、独自のバージョンの関数を呼び出すようになりました。 – Spalteer

+1

ライブラリは実行可能なシンボルを見ないので、 '-fvisibility = hidden'で実行可能ファイルをコンパイルすると動作します。しかし、図書館間のシンボルミスマッチの可能性はまだあります。ライブラリシンボルの可視性を制限する方がよい - 編集を参照。 –

関連する問題