2009-07-03 4 views
0

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

APIの共有オブジェクトlibdrmaa.soはコンパイル時にリンクされ、
私のアプリケーションを使っているクライアントがこの ".so"を持っていても問題ないですが、クライアントがそれを持っていない場合には、 共有ライブラリをロードできません。
これを避けるため、APIコールをdlsym()とdlopen()を使用して取得した関数ポインタに置き換えました。 dlopenへの呼び出しが成功せず、私の目的が達成されたら、グリッドの代わりにローカルマシンを使用できます。
問題は今、アプリケーションが小さなテストケースでうまく動作するようになりましたが、大規模なテストケースでは、動的ロードを使用する同じコードが正しく動作している間にセグメント化エラーが発生します。C動的ロードルーチンを使用する際の問題

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

ご協力いただければ幸いです。

ありがとう、

答えて

3

dlsym()でロードされたコードでは、動的ロードによってseg-faultが発生するという直接的な問題はほとんどありません。

何がしている可能性があります別の問題を露呈している、おそらく物事を移動することによって。これはおそらく、静的リンクの場合には正当なものを指しているが、動的リンクの場合には他のどこかを指す迷いのある(初期化されていない)ポインタを意味します。確かに、それは長期的にはあなたにとって有益です。そうでなければ、長い間発見されていないかもしれない問題があることを示しています。

これは特に、大きなテストではなく小さなテストで発生すると言われています

+0

ええ..私はあなたに同意します..しかし、私はこれを修正する方法は?全体のコードはかなりかさばっています:(.. – sud03r

+0

最初の段階は、seg-faultを引き起こしているものを解決することです。データへのヌルポインタアクセス、または関数ポインタへのアクセスか、それとも何か他の問題ですか?また、コアダンプ(デバッグを有効にしてコンパイルされたプログラムの)から、呼び出し点のスタックを追跡する必要があります。スタックのバックトレースが壊れている、バッファのオーバーフローが問題である可能性があります。十分な領域があるかどうかチェックせずにデータを保存しようとしましたが、そうでなければ、クラッシュ時に。幸運、これらのバグはイライラする可能性があります。 –

0

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

DLL(または共有ライブラリ)を使用している場合、通常これに対処するには、C++オブジェクトを返す1つのC関数が必要です。その後、残りの対話は、DLLから返されたC++オブジェクトと相互作用します。

このパターンは、オブジェクトのようなファクトリを示唆しているので、DLLはvoid *を返す1つのextern "C"関数を持たなければなりません。これはreinterpret_cast <>をC++ファクトリオブジェクトに戻すことができます。

1

Jonathan Leffler氏によると、この問題はAPIを直接使用している場合にはおそらく存在します。まだクラッシュを起こしていないだけです。

あなたが得るときSIGSEGVは、結果のコアダンプ(または単にデバッガで直接アプリを実行)を分析する必要があり、それがクラッシュした場所を探してあなたの非常に最初のステップは。私は$ 0を賭けるでしょう。02 mallocまたはfreeのどこかでクラッシュすることがあります。この場合、問題は普通の古いヒープの破損であり、ヒープチェッカーのツールが多数あります。 Solarisはwatchmallocを提供しています。これは良いスタートです。

関連する問題