2009-07-13 6 views
4

を主張WindowsのCRTは、アプリケーションがassert(false)にヒットし、時にはそれが何回も作成して、私を満たしている場合ウィンドウ「を中止、再試行は、無視する」が表示されます画面。WindowsのCRTとデバッグモードでの報告(無視、再試行、中止)

アサートがデバッガで壊れてしまい、私に質問がない場合、私はそれが大好きです。

私はCRT reporting flagsを変更しましたが、これは効果がありませんでした。

reporting hookも変更しようとしました。それは25-30 "Abort"ダイアログが表示された後に呼び出されます。

私はDLLが役立つ場合は、別のプログラムによってロードされています。また、私のDLLをロードしているホストプログラムが、自分のコードを呼び出すスレッドと一貫していないように見えます。 スレッドの1つが停止したように見えますが、残りのスレッドはまだ実行中です。

これを行うにはどうすればCRTを設定しますか?

答えて

5

これは(VS 2008上で、少なくとも私にとっては)作品: は

int __cdecl CrtDbgHook(int nReportType, char* szMsg, int* pnRet) 
{ 
    return TRUE;//Return true - Abort,Retry,Ignore dialog will *not* be displayed 
    return FALSE;//Return false - Abort,Retry,Ignore dialog *will be displayed* 
} 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 
{ 
    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, CrtDbgHook); 
    assert(false); 
    getch(); 
    return 1; 
} 

ます。また、これが表示されることに注意してください(あなた自身のassertのような挙動を書くことができ(基本的には、フック関数からTRUEを返します) 「Break、Continue」ダイアログ):

#define MYASSERT(x) { if(!(x)) {DbgRaiseAssertionFailure();} } 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 
{ 
    MYASSERT(false); 
    getch(); 
    return 1; 
} 

希望すると助かります!

+0

残念ながら、これは私の問題を解決しません。 CrtDbgHookが呼び出される前に、約25-30 Abort、Retry、Ignoreダイアログを表示します。 – Ted

0

なぜそれがアサートされますか? assert(false)は、CRTでコードが実行されたとします。もし私があなただったら私は怖いでしょう。それは常に1つの行にありますか?その周辺にコメントはありますか?

EDIT: 私は、あなたが満たさないことをチェックしていると仮定しているため、CRTコードでアサートが発生します(混在したランタイムにリンクしたり、管理対象のC++アセンブリを作成して手動で初期化しなかったCRT、またはDllMain内からLoadLibraryを呼び出そうとしている、または何も起こらないはずのもの)。

したがって、アサートを抑制する方法を理解する前に、最初にアサートする理由を正確に調べてください。そうしないと、後で無関係な問題が起こる可能性が高くなり、それらをデバッグしようとすると多くの楽しみがあります。 (あなたがそれらを約ある主張するものを知っている場合は、あなたの質問から、それは不明である)

この

if(somebadcondition) 
{ 
    assert(false); 
    // recovery code 
} 

のようなコードは、文字通り「このコードの分岐が実行されてはいけません」という意味。

+0

アサルト(false)がアサートする理由は何ですか?なぜなら、あなたが主張するとき、その条件は真であると評価され、 "+ b = 4を主張する"という思考は、+ bが4に等しくなければ、 "主張は失敗した"。 – Liao

+0

申し訳ありませんが、最後の2つの質問は分かりません。どのようなコメントでも "周り" - 何を意味するのですか? – Liao

+0

あなたは、アサーションがなぜ発生しているのか最初に理解しなければならないという点で、まったく正しいです。そしてassert(false)を使う。確かに "このコードの枝は決して実行されてはならない"ということを確実にする一つの方法です。 +1これ以上の情報/正しい練習を追加するための+1、私は無視した。 – Liao

2

遼の答えは道のほとんどが表示されますが、私はあなたのデバッグフックにもう一つを追加することを提案したいと思います。そうしないと、あなたの主張はただ消えます

int __cdecl StraightToDebugger(int, char*, int*) 
{ 
    _CrtDbgBreak(); // breaks into debugger 
    return TRUE; // handled -- don't process further. 
} 

をし、プロセスは終了します。

このアプローチの問題点は、少なくともVC Expressの自宅でのインストールでは、デバッガが通常のアサーションエラーの代わりに大きな "program.exeがブレークポイントをトリガしました"というメッセージをスローするためです。大きな改善になります。

1

assertの動作をしたいのか、特定の行のデバッガに無条件で侵入する汎用パターンとして具体的にassert(false)を使用しようとしているのかどうかはわかりません。それが前者なら、遼と金の答えを見てください。後者の場合は、代わりに__debugbreak組み込み関数を実際に使用する必要があります。

+0

'assert'がデバッグビルドでのみブレークしトリガするように要求する違いはありますが、' __debugbreak'は関係なく中断しますか? – thomthom

+1

__debugbreakは文字通りコード内にブレークポイント命令(x86のINT 3など)を入れます。つまり、ビルドで壊れてしまい、テキストなどの素晴らしいメッセージボックスは表示されません。 –

0

なぜ使用しないのですかDebugBreak Function

オペコードを使用することもできますか? /CLRでコンパイルしたとき

__asm int 3はネイティブコードが生成されることはありませんでした

#ifdef _X86_ 
#define BreakPoint()  _asm { int 3h } 
#else 
#define BreakPoint()  DebugBreak() 
#endif 

Before Visual C++ 2005, the instruction、。コンパイラは 命令をCLRブレーク 命令に変換しました。 Visual C2005年から__asm int 3が 関数のネイティブコード生成 になりました。関数を にするとコードにブレークポイントが発生し、その関数を MSILにコンパイルする場合は をコンパイルするには__debugbreakを使用します。

+0

定義を変更したくありませんassertマクロの これは私のコードだけでなく、私がアサルトマクロを使用する静的ライブラリについても書かれています – Ted

+0

私は変更を提案しませんでした、これはMicrosoftのヘッダファイルです... – zproxy

関連する問題