0

C++ で記述されたさまざまなモジュールで構成されるアプリケーションがあります。
モジュールの 1 つは、SunGrid Engine で分散タスクを処理するためのものです。クライアントがグリッドをサポートしていない場合は、ローカル マシンを使用する必要が

あります API libdrmaa.so の共有オブジェクトは、コンパイル時にリンクされ、実行時にロードされます。
私のアプリケーションを使用しているクライアントがこの「.so」を持っている場合、すべて問題ありませんが、クライアントがそれを持っていない場合、アプリケーションは共有ライブラリのロードに失敗して終了します。
これを回避するために、API 呼び出しを dlsym() と dlopen() を使用して取得した関数ポインターに置き換えました。dlopen の呼び出しが成功せず、目的が達成された場合、グリッドの代わりにローカル マシンを使用できるようになりました。
現在の問題は、アプリケーションが小さなテストケースでは正常に実行されるようになったことですが、大きなテストケースではセグメンテーション エラーがスローされますが、動的読み込みを使用する同じコードは正しく機能します。

dlsym() と dlopen() を使用しているときに何か不足していますか?
同じ目標を達成する他の方法はありますか?

どんな助けでも大歓迎です。

ありがとう、

4

3 に答える 3

3

dlsym()動的ロードによってセグメンテーション違反が発生するという意味で、ロードされたコードに直接的な問題が発生する可能性はほとんどありません。

おそらく何かを移動することによって、別の問題を明らかにしている可能性があります。これはおそらく、静的リンクの場合は「正当な」場所を指しているが、動的リンクの場合は別の場所を指している浮遊した(初期化されていない)ポインターを意味し、他の場所がセグフォールトをトリガーします。確かに、これは長い目で見ればあなたにとってメリットがあります。そうでなければ、長い間検出されないままになる可能性のある問題があることを示しています。

これは、小さなテストではなく、より大きなテストで発生すると述べているため、特に可能性が高いと考えています。

于 2009-07-03T15:41:59.923 に答える
1

Jonathan Leffler が言うように、API を直接使用している場合に問題が発生する可能性が非常に高くなります。まだクラッシュを引き起こしていないだけです。

を取得したときの最初のステップSIGSEGVは、結果のコア ダンプを分析し (またはデバッガーでアプリを直接実行するだけ)、クラッシュした場所を調べることです。mallocまたは内のどこかでクラッシュしていることに $0.02 を賭けます。freeこの場合、問題は単純な古いヒープの破損であり、それを見つけるのに役立つ多くのヒープ チェッカー ツールが利用可能です。Solaris には が用意されておりwatchmalloc、これは良い出発点です。

于 2009-07-05T01:14:23.810 に答える
0

extern "C" 関数で例外をスローしている場合は、アプリケーションを終了する必要があります。これは、C ABI には例外を伝搬する機能がないためです。

DLL (または共有ライブラリ) を使用するときにこれに対抗するには、通常、C++ オブジェクトを返す 1 つの C 関数を使用します。次に、DLL から返された C++ オブジェクトとのやり取りが残ります。

このパターンは、ファクトリのようなオブジェクトを示唆しています (そして私は強く示唆しています)。したがって、DLL には、C++ ファクトリ オブジェクトに reinterpret_cast<> できる void* を返す単一の extern "C" 関数が必要です。

于 2009-07-03T15:30:13.617 に答える