2

私はさまざまなサイトを見回しましたが、この質問に対する答えは見つかりませんでした。タイトルが示すように、作業中のライブラリがクラッシュした場合にキャッチする方法を見つけようとしています。ライブラリにある多くのマネージャ スタイル クラスのインスタンスを保持する Root クラスがあり、デストラクタでインスタンスを解放します。当然のことながら、マネージャーはかなりの量のデータを担当しているため、データを適切に破棄しないと、かなり許容できない、さらには危険なレベルのメモリ リークが発生する可能性があります。

プログラムがクラッシュすると、OS がプログラムのスタック領域の割り当てを解除することは承知していますが、割り当てられたオブジェクトのデストラクタの呼び出しは含まれません。また、実行中に割り当てられたヒープを削除することも含まれていません。これは、ライブラリ内の大量のメモリを処理する方法であり、広範なメモリ リークの問題に戻ります。

私が他のサイトで見つけた多くの回答は、関数を に登録するように言っているだけatexit()ですが、アプリケーションがクラッシュした場合、その関数は機能しません。そして、前述のように、クラッシュはデストラクタを呼び出さないため、破棄されたときにすべてを閉じるグローバル シングルトンを作成する方法はありません。私のもう 1 つの考えは、ライブラリのエンド ユーザーが適切な予防策を講じてクラッシュを回避することを期待することでした (例外スローの広範な使用を通じて)。それに対処するためにエンドユーザーに少し多くのことを求めています。

TL;DR の質問は次のとおりです。標準の C++ 関数または何らかのマネージャー クラスを使用して、ライブラリがクラッシュしたときにそれをキャッチして適切に処理する方法はありますか?

編集:また、これに対処するには、クロスプラットフォームの方法を本当に好みます。私のコード ベースは C++11 の機能を多用しているため、使用可能なコンパイラを GCC と Clang の最新バージョンにプログラムで制限しました。

それだけでなく、ファイル システムへのストリームを閉じて、終了ステータスに関するいくつかのメッセージを出力する Logger などのクラスもいくつかあります。ファイルへのメモリリークの可能性を報告するメモリトラッカーもありますが、デストラクタでのみです。

4

2 に答える 2

2

「標準の C++ 関数またはある種のマネージャ クラスを使用して、ライブラリのクラッシュをキャッチして適切に処理する方法はありますか?」

私が想像できるあなたの質問に対する最も簡潔な答えは次のとおりです。

C++ 標準エラー処理のクラスとカテゴリに固執します。


あなたが求めているようにatexit()、動作は標準リファレンスでも明確に定義されています。

のような追加のハンドラー メカニズムがあることに注意std::terminate_handlerしてください。これにより、いくつかの例外的なアボート状況を、移植可能で標準に準拠した方法で処理できます。

最後になりましたが、特定の (OS 固有の)シグナル ハンドラーをインストールして、スタック オーバーフローなどによって発生した、いわゆるセグメンテーション違反などのエラーをキャッチする必要がある場合があります。 (SIGSEV)

于 2014-08-05T19:01:29.223 に答える
1

TL;DR の質問は次のとおりです。標準の C++ 関数または何らかのマネージャー クラスを使用して、ライブラリがクラッシュしたときにそれをキャッチして適切に処理する方法はありますか?

構造化された例外処理、さまざまなセグメンテーション違反、バス エラー (標準ではこれらのいずれについても何も言及されていません) が存在する場合、ライブラリのクラッシュによってユーザーのアプリケーションがダウンするのを防ぐ唯一の方法は、ライブラリを次の方法で提供することです。クライアント プログラムが実行するバイナリであり、クライアント プロセスが終了したかどうかを監視する責任をクライアントに持たせます。

ライブラリをユーザーのアプリケーションに直接リンクしたい場合、ライブラリのバグによってユーザーのアプリケーションがクラッシュしないことを確実にするためにできることは何もありません。それが、ユニット、サブシステム、およびシステム テスト スイートの目的です。ライブラリがアプリケーションをクラッシュさせた場合、私が認識しているほぼすべての OS が割り当てられたすべてのリソースを再利用するため、ヒープ メモリを解放するためのグローバル シングルトンは必要ないことに注意してください。OS によって自動的に要求されますクラッシュのポイント。

最後に、ライブラリがクラッシュした場合、プロセスはすでに悪い状態になっていることに注意してください。ログメッセージの書き込みやメモリリークステータスのダンプなど、その時点でコードを安全に実行する方法はありません(たとえば、プロセスヒープが破損している場合)。

于 2014-08-05T19:39:16.877 に答える