2013-08-02 18 views
5

私はBoost.threadを内部的に使用する共有ライブラリを構築しています。その結果、Boost.sthreadはそれに依存するので、Boost.systemも使用されます。私の共有ライブラリはCインターフェイスをエクスポートするので、私はすべての内部例外処理とスレッド使用法などをエンドユーザーから隠蔽する必要があります。話すにはブラックボックスになっているはずです。しかし、プログラムがうまく動作している間にクライアントアプリケーションにリンクすると、ライブラリ関数を呼び出すことによって処理を停止するとすぐに、私は次のようになります:共有ライブラリ内の内部例外がエンドユーザアプリケーションを終了する

'boost :: thread_interrupted '

私はこの例外をライブラリで内部的にキャッチします。なぜ、実際にキャッチされていないのかわかりません。エンドユーザーのプログラムは、Boost例外を何らかの方法で知り、処理することを目的としたものではありません。共有ライブラリをビルドするときは、Boost.threadとBoost.systemの両方に静的リンクを使用するので、外部の世界はそれらを見ることは決してありません。私はUbuntu 12上でGCC 4.7を使用しています。Windowsでは、このような問題はありません(MSVCまたはMinGwでは問題ありません)。

(EDIT)

私は、コメント内の要求に従って、問題を再現する最小限の例を示すために、質問を編集しています。

最初はtestlib.cppとtestlib.hのコードです。

testlib.cpp:

 
#include <boost/thread/thread.hpp> 

void thread_func() 
{ 
while(1) 
{ 
boost::this_thread::interruption_point(); 
} 
} 

void do_processing() 
{ 
// Start a thread that will execute the function above. 
boost::thread worker(thread_func); 

// We assume the thread started properly for the purposes of this example. 

// Now let's interrupt the thread. 
worker.interrupt(); 

// And now let's wait for it to finish. 
worker.join(); 
} 

そして今testlib.h:

私は、次のコマンドを使用して共有ライブラリにこれを構築

 
#ifndef TESTLIB_H 
#define TESTLIB_H 

void do_processing(); 

#endif 

グラム++ -static-libgccの - 静的-s -DNDEBUG -I/usr/boost_1_54_0 -L/usr/boost_1_54_0/stage/lib -Wall -shared -fPIC -o libtestlib.so testlib.cpp -lboost_thread -lboost_system -lpthread -O3

はその後、私は次のように見える些細なクライアントプログラムのコードを持っている:

 
#include "testlib.h" 
#include <cstdio> 

int main() 
{ 
do_processing(); 
printf("Execution completed properly.\n"); 
return 0; 
} 

次のように私はクライアントを構築:

グラム++ -DNDEBUG -Iは/ usr/boost_1_54_0 -L ./私は、クライアントを実行すると-O3

-ltestlib -Wall -oクライアントclient.cppは、私が取得:

を '後押し:: thread_interrupted'
のインスタンスを投げた後に呼び出さTERMINATE 10 Aborted(コアダンプされた)

私は明示的にスレッド中断例外をキャッチしていませんが、Boostのドキュメントに従ってBoost.threadはそれを行い、指定されたスレッドのみを終了します。私は明らかにthread_func関数内から例外をキャッチしようとしましたが、違いはありませんでした。

(EDITの終わり)

(EDIT 2)

それは-fexceptionsをオンにしてもして、それでも問題が解決しないことは注目に値します。また、私は例外をキャッチしてスローするコードと同じ翻訳単位で定義された例外をスローしてキャッチしましたが、改善はありませんでした。要するに、すべての例外は、共有ライブラリに捕捉ハンドラがあるにもかかわらず、共有ライブラリで捕らえられていないように見えます。クライアントファイルとtestlibファイルを単一のプログラムの一部としてコンパイルすると、つまりtestlibを共有ライブラリにしなくても、すべてが期待通りに機能します。

(終了の編集2)

ヒントはありますか?

+6

私は問題を示す***最小限の***テストを作成することをお勧めします(5行のMakefileを考えてください)。 github/gistに載せてください。可能性がありますが、その過程で原因や回避策が見つかります。そうでない場合は、実際に私たちに何かを見せてくれるでしょう。 – sehe

+2

@このようなコメントは無限に、特に 'チャンスはありますか、あなたはそのプロセスの原因/回避策を見つけるでしょう'と言ってください。無数の再生コードを取得しようとしている間に、自分自身で解決することを見つけるために、私はちょうど質問を始めました。 – stijn

+0

@stijn私は知っています。正直言って、私はそれを言いました。なぜなら、今のように、野生の推測のほかに、文字通り他の選択肢がないからです。私は本当にこれを調べるのを手伝っていますが、何も進んでいません。 – sehe

答えて

1

私はついにそれを理解しました。 -sharedが指定されている場合は、-staticフラグを指定しないでください。私が信じるのは、リンクするライブラリの静的なバージョンを好むようにリンカーに指示しただけで、生成されたダイナミックライブラリはダイナミックリンクには適していません。これはちょっと皮肉です。しかしそこにはあります。 -staticを削除するとすべての問題が解決し、例外を完全に処理するダイナミックライブラリ内でBoostを静的に正しくリンクすることができます。

0

this?あなたがEをスローライブラリLを持っている場合は

、その後、Lと アプリケーションAの両方がXに対してリンクされなければならない、E.

の 定義

てみてくださいを含むライブラリーはに対して実行可能リンクしますブーストも。

+0

残念ながら、それは私にとってはうまくいかないでしょう。ライブラリはエンドユーザー向けであり、内部のすべての依存関係は静的にリンクされているため、クライアントアプリケーションはそれらを気にする必要がありません。 Boostへの依存を強制することはできません。 –

+0

さらに明確にするために、アプリケーション(a)はeについて知ることを意味しません。私は自分自身の別の部分でスローとキャッチをすることになっていますが、eは決してeを見るはずがありません。 –

0

それ自体静的にリンクされたライブラリを含む共有ライブラリはあまり良い考えではありません。このシナリオはGNUツールチェーンではうまくサポートされていないと思います。

私はあなたの特定の問題がオプション-static-libgccから発生すると思いますが、自分のマシンでオプションでコンパイルできませんでした。静的にdinamicallyをlibpthread.soにリンクするのは良いアイデアのように聞こえます...メインの実行可能ファイルが独自のスレッドを作成したい場合はどうなりますか?それは-pthreadとコンパイルされますか?そうであれば、スレッド関数を2回リンクします。そうでなければ、関数は持ちますが、プリコンパイラ・マクロもスレッドセーフなライブラリ関数もありません。

私の助言は、ライブラリを静的にコンパイルするのではなく、単にLinuxの方法ではありません。

実はそれはあなたがブーストの配布バージョンに依存したくない場合でも、本当の問題になることはありません:共有ブーストライブラリに対してプログラムをコンパイルし、すべてのこれらのファイル(libboost_thread.so.1.54.0libboost_system.so.1.54.0libtestlib.so)への展開同じディレクトリ。次に、LD_LIBRARY_PATH=<path-to-so-files>でプログラムを実行します。クライアントはブーストを直接使用するつもりはないので、ブースト・ヘッダーは必要なく、コンパイラー・コマンドでリンクすることもできません。あなたはまだあなたのブラックボックスを持っていますが、今では1つではなく3つのファイルで形成されています。

+0

私のライブラリーの中でそのライブラリーの中で宣言された例外も捕らえられません。これはBoostをまったく含まなくても起こり、-static-libgccオプションが存在しない場合に起こります。 Boostを含めるようにユーザーを強制することは、私がやりたいことではなく、ユーザーが自分の内部の依存関係を気にする必要がある場合、もはやブラックボックスではありません。 pthreadに動的にリンクするのは問題ありませんが、Boostは別の話です。私が言及したように、例外の問題はBoostなしでも存在し、例外タイプが定義されていても、スローされてライブラリ自体の中に捕まえられます。 –

関連する問題