0

私は、多くの MFC 文字列書式設定関数を持つ C++ プロジェクト (私は作成者ではありません) を使用しています。残念ながら、 と のようなもの%d%s(キーボード上の d と s の文字の位置を含めて) 非常に近くにあるため、別の文字と入れ替えることができます。そのため、次のようなコード行を目にすることがあります。

CString s;
s.Format(L"Value v=%s", 100);    //Should've been %d instead

これにより、プロセスのハード クラッシュが発生し、最終的なプロジェクトで特定して分離することが非常に困難になります。そのため、関数を独自のオーバーライドでラップしFormat、例外をキャッチして、未処理の例外としてスローされる前にログに記録することを考えていました。

そこで、次の構成を採用しました。

__try
{
    //Do the Format function here
}
__except(1)
{
    //Log the error, etc.
}

しかし、残念ながら、上記の構成は最初のコード チャンクからの例外をキャッチしなかったため、VS 2008 C++ デバッガーを起動して、次のように表示しました。

ここに画像の説明を入力

次に、これを試しました:

try
{
    //Do the Format function here
}
catch(int e)
{
    //Do the logging
}

しかし、それも聞き取れませんでした。

では、どうすればその障害をキャッチできますか?

PS。そして、2 つ目の質問があります。たとえばFormatのような MFC 関数をオーバーライドする簡単な方法はありますか?

4

3 に答える 3

0

MFC はCExceptionポインターをスローするので、これを試すことができます。

try
{
    // Do the Format function here
}
catch(CException* e)
{
    // Do the logging then free the exception
    if (m_bThrowExceptionAgain)
        throw; // Do not delete e 
    else 
        e->Delete();
}

例に示すように、例外オブジェクトをキャッチしたら削除する必要があります。また、コンパイラで C++ 例外が有効になっていることを確認してください。詳細については、 http://msdn.microsoft.com/en-us/library/0e5twxsh.aspxを参照してください。

于 2013-09-13T02:06:57.337 に答える
0

他の人がすでに言っているように、低レベルの例外 (アクセス違反など) は C++ の例外と同じではありません。それらは構造化された例外処理という用語に該当し、少なくともデフォルトでは、キャッチするために他の手段が必要になります。

コンパイラの設定を (少なくとも Visual Studio で) 変更して、これらの例外を C++ の try/catch ステートメントで処理できるものにラップすることは可能ですが、思い出すと、SEH 例外の内容とその発生元の詳細が失われます。

何らかの方法で例外を取得して、これらの問題を追跡するのに十分に役立つ可能性がありますが、静的コード分析を使用する別の方法もあります。

標準の C++ コンパイラは通常、format/printf スタイルの呼び出しを検証しませんが、さまざまなツールが検証します。実際、Visual Studio の最近のバージョン/エディションにはコード分析ツールが付属していますが、あなたが言及した VS 2008 では利用できなかった可能性があります。したがって、いくつかの調査を行い、実行時ではなく分析/コンパイル時に CString::Format のすべての間違いをキャッチできる何らかのコード分析ツールを手に入れることができるかどうかを確認することは価値があるかもしれません。

于 2013-09-13T04:17:46.447 に答える