12

私は別のチームによってCで書かれたライブラリを使用するC++アプリケーションに取り組んでいます。ライブラリの作成者は、exit()エラーが発生したときに呼び出すことを好みます。これにより、C++アプリケーションのスタック上のオブジェクトのデストラクタを呼び出さずにプログラムがすぐに終了します。アプリケーションは、プロセスの終了後にオペレーティングシステムによって自動的に再利用されない一部のシステムリソース(共有メモリ領域、プロセス間ミューテックスなど)を設定するため、これは問題です。

アプリとライブラリの両方の完全なソースコードを持っていますが、ライブラリは非常に確立されており、単体テストがないため、変更するのは大変です。exit()アプリの正常なシャットダウンを実装できるように 、呼び出しを「フック」する方法はありますか?

私が検討している1つの可能性、アプリケーションである1つの大きなクラスを作成することです。つまり、すべてのクリーンアップは、そのデストラクタまたはそのメンバーの1つのデストラクタで行われます。次に、これらの大きなオブジェクトの1つをヒープに割り当てmain()、グローバルを設定します。それを指すポインタ、およびatexit()グローバルポインタを介してオブジェクトを削除するだけのハンドラを登録するために使用します。それはうまくいく可能性がありますか?

この問題に取り組むための既知の良い方法はありますか?

4

4 に答える 4

14

最悪の場合、exitシステム自体の実装ではなく、いつでも独自の実装を記述してリンクすることができます。そこでエラーを処理し、オプションで_exit(2)自分自身を呼び出すことができます。

ライブラリソースがあるので、さらに簡単です。-Dexit=myExitビルド時にフラグを追加してから、の実装を提供するだけですmyExit

于 2013-01-07T16:14:34.120 に答える
4

atexitを使用してexitハンドラーをインストールし、目的の動作を実装します

于 2013-01-07T16:16:39.347 に答える
2

CライブラリをC++からより使いやすくしたい場合は、別のプロセスで実行できます。次に、(終了ハンドラーなどを使用して)終了時に、メインアプリケーションプロセスが例外を認識してスローし、自身のスタックをアンワインドすることを確認します。場合によっては、致命的ではない方法でエラーを処理できる可能性があります。

もちろん、ライブラリの使用を別のプロセスに移動することは、簡単ではないか、特に効率的ではない場合があります。インターフェイスをラップし、選択したIPCメカニズムを介して入力と出力をコピーするために行う必要のある作業がいくつかあります。

ただし、メインプロセスからライブラリを使用するための回避策として、説明したものが機能するはずです。リスクは、クリーンアップが必要なすべてのものを識別して分離できないこと、またはスタックが正常に巻き戻されることを前提として、将来誰かがアプリケーション(または使用する別のコンポーネント)を変更することです。

ライブラリソースを変更して、を呼び出す代わりに、ランタイムまたはコンパイル時に構成可能な関数を呼び出すことができますexit()。次に、例外処理を使用してライブラリをコンパイルし、C++で関数を実装して例外をスローします。それに関する問題は、ライブラリ自体がエラー時にリソースをリークする可能性があることです。そのため、スタックを巻き戻すためだけにその例外を使用する必要があります(そしておそらくエラー報告を行います)。アプリに関する限り、エラーが致命的ではない可能性がある場合でも、それをキャッチして続行しないでください。

于 2013-01-07T16:27:19.763 に答える
1

またはではexitなく呼び出しの場合、再度制御を取得するためのいくつかのポイントがあります。assertabort

  • を呼び出すときexit、静的な有効期間を持つオブジェクト(基本的に:グローバルおよびで宣言されたオブジェクト)のデストラクタstaticは引き続き実行されます。これは、(少数の)グローバル「リソースマネージャー」オブジェクトをセットアップし、それらのデストラクタでリソースを解放できることを意味します。
  • すでに見つけたように、フックをに登録することができますatexit。これは1つに限定されません。もっと登録できます。

他のすべてが失敗した場合、ライブラリのソースがあるため、いくつかのマクロトリックを実行して、への呼び出しをexit、たとえば例外をスローする可能性のある独自の関数に効果的に置き換えることができます。

于 2013-01-07T16:52:23.830 に答える