私は現在、Windows MSVC++ (9.0) アプリ用の例外ベースのエラー報告システム (つまり、例外構造と型/継承、コール スタック、エラー報告とログ記録など) に取り組んでいます。
私の質問は次のとおりです。メモリ不足エラーを正しく報告してログに記録する方法は?
このエラーが発生した場合、たとえばopbad_alloc
によってスローされたnew
場合、多くの「機能」が利用できない可能性があり、主に追加のメモリ割り当てに関するものです。通常、lib で例外がスローされた場合はアプリケーションに例外を渡し、メッセージ ボックスとエラー ログ ファイルを使用して報告し、ログに記録します。もう 1 つの方法 (主にサービス用) は、Windows イベント ログを使用することです。
私が抱えている主な問題は、エラーメッセージを組み立てることです。
エラー情報を提供するために、静的なエラー メッセージ (文字列リテラル、メッセージ ファイルのエントリ、FormatMessage の使用) を定義し、コール スタックなどのランタイム情報を含めたいと思います。
この用途に必要な関数/メソッド
- STL (
std::string, std::stringstream, std::ofstream
) - ブラウン管 (
swprintf_s, fwrite
) - または Win32 API (
StackWalk64, MessageBox, FormatMessage, ReportEvent, WriteFile
)
MSDN で文書化されている以外に、Windows では多かれ少なかれ (Win32) または少なめ (STL) のクローズド ソースであるため、メモリ不足の問題でそれらがどのように動作するかはよくわかりません。
問題がある可能性があることを証明するために、bad_alloc を引き起こす簡単な小さなアプリを作成しました。
int main()
{
InitErrorReporter();
try
{
for(int i = 0; i < 0xFFFFFFFF; i++)
{
for(int j = 0; j < 0xFFFFFFFF; j++)
{
char* p = new char;
}
}
}catch(bad_alloc& e_b)
{
ReportError(e_b);
}
DeinitErrorReporter();
return 0;
}
デバッガーを接続せずに 2 つのインスタンスを実行しましたが (リリース構成、VS 2008)、「何も起こりませんでした」。つまり、エラー レポートで内部的に使用した ReportEvent または WriteFile からのエラー コードはありませんでした。次に、デバッガーを使用してインスタンスを 1 つ、デバッガーを使用せずにインスタンスを 1 つ起動し、ReportError 行のブレークポイントを使用して、エラーを次々に報告しようとします。これは、デバッガーが接続されたインスタンスで正常に機能しました (問題のない LocalAlloc を使用しても、正しく報告され、エラーがログに記録されました)! しかし、タスクマンは、アプリが終了する前に大量のメモリが解放されるという奇妙な動作を示しました。例外がスローされたときだと思います。
複数のプロセス [編集] と複数のスレッド [/編集] が多くのメモリを消費している可能性があることを考慮してください。そのため、事前に割り当てられたヒープ領域を解放することは、報告したいプロセスのメモリ不足環境を回避するための安全な解決策ではありません。エラー。
前もって感謝します!