2009-06-17 8 views
4

私はftestというテストプログラムを持っています。テストを含む.soファイルをロードし、そこで見つかったテストを実行します。これらのテストのうちの1つは、O/RMのPostgresデータベースドライバを含む.soをロードして実行します。共有オブジェクト(.so)からのLinux上の例外

Postgresドライバが.soファイル(またはリンク先のftestはリンクされていません)に定義されている例外をスローし、テストフレームワークがキャッチした場合、例外デストラクタはsegfaultをトリガします。

このsegfaultは、コンパイルされた例外が(dloadを使用して)動的にロードされた.soにあるたびに発生します。

この種類のものは、Windowsでは同じアーキテクチャを使用しても問題ありません。コアライブラリからの例外のみを使用するように自分自身を制限したくはありません。アドインは、独自の例外クラスを作成して正常に処理する必要があります。

例外は、std :: exceptionのサブクラスです。場合によっては例外がライブラリ(libpqxxなど)で定義されていることもあります。

例外は何か使用してスローされます。

throw exception_class(exception_arguments); 

をそして使用してキャッチされています

catch (std::exception &e) { 
    // handler code 
} 

は、この作業を取得するために必要ないくつかの特別なコンパイラオプションはありますか? throw new exception_class(args)で例外をスローするように切り替える必要がありますか(これは本当にしたくありません)。

答えて

6

ご使用のgccを仮定 -

追加-Wl、-Eときに実行可能な呼び出しdlloadを構築します()。実行可能ファイルからすべての型情報シンボルがエクスポートされるため、RTTI(例外をキャッチするとき)が正しく機能するはずです。

VC++は文字列比較を使用してtypeinfoと一致させ、より遅いdynamic_cast <などを生成しますが、より小さなバイナリを生成します。 g ++はポインタ比較を使用します。

実行時ロード.soで実装された純粋仮想インターフェイスクラスを使用しようとしたときに同じ問題が発生しました。

ネット上に浮かんでいる被写体に関連する記事がいくつかあります。

希望があれば、 ヘイマン。

+0

実際には、キャッチではなく問題を抱えるデストラクタです。仮想テーブルの場所であれば驚くことはありません。おそらく、.soはテーブルが読み込まれたページに読み込み権限を与えないので、デストラクタは読み込めません。それは純粋な推測です。 Boost.Buildでこれらのオプションを設定する方法がわかりますか? – KayEss

+0

-Wl、Eは何の違いも生じていないようです:( – KayEss

+0

実際、私は-Wl、Eが効果を持っていたと思います。例外が発生する前に.soがアンロードされているという2番目の問題がありましたこれらの両方を修正すると、segfaultsなしで動作する例外が発生します。 – KayEss