次の単純なソース(test.cppという名前)を使用します。
#include <windows.h>
void main()
{
DebugBreak();
}
次のコマンドを使用して、これをコンパイルしてリンクします。
cl /MD /c test.cpp
link /debug test.obj
TEST.EXEが(64ビットのWindows 7システムで)実行されると、次のダイアログが表示されます。
次に、次のソースファイルを追加します(test2.cppという名前を付けます)。
void hello()
{
}
そして、これをコンパイルして、次のように最初のソースとリンクします。
cl /MD /c test.cpp
cl /MD /c /clr test2.cpp
link test.obj test2.obj
hello-functionを呼び出さず、リンクしただけであることに注意してください。
次に、TEST.EXEを再度実行します(同じ64ビットWindows 7システムで)。上記のダイアログの代わりに、次のように表示されます。
どうやら、.Net Frameworkでリンクすると、DebugBreakの動作が異なります。どうしてこれなの?そして、どうすれば古いDebugBreakの動作を元に戻すことができますか?これはおそらくWindows7または64ビット固有の動作ですか?
DebugBreakを使用する理由を明確にするための補足:カスタムassert-framework(JohnRobbinのDebuggingWindows ApplicationsブックのSuperAssertのようなもの)があり、開発者がデバッガーにジャンプできるようにDebugBreak関数を使用します(または、問題がある場合は、新しいデバッガーを開きます)。これで、単純なポップアップのみが表示され、デバッガーにジャンプすることはできなくなりました。
別の解決策として、ゼロ除算または無効なアドレスへの書き込みを実行することもできますが、これはあまりクリーンな解決策ではありません。
編集: これは2番目のテスト(単純なダイアログ)の呼び出しスタックです:
ntdll.dll!_NtRaiseHardError@24() + 0x12 bytes
ntdll.dll!_NtRaiseHardError@24() + 0x12 bytes
clrjit.dll!Compiler::compCompile() + 0x5987 bytes
clr.dll!RaiseFailFastExceptionOnWin7() + 0x6b bytes
clr.dll!WatsonLastChance() + 0x1b8 bytes
clr.dll!InternalUnhandledExceptionFilter_Worker() + 0x29c bytes
clr.dll!InitGSCookie() + 0x70062 bytes
clr.dll!__CorExeMain@0() + 0x71111 bytes
msvcr100_clr0400.dll!@_EH4_CallFilterFunc@8() + 0x12 bytes
msvcr100_clr0400.dll!__except_handler4_common() + 0x7f bytes
clr.dll!__except_handler4() + 0x20 bytes
ntdll.dll!ExecuteHandler2@20() + 0x26 bytes
ntdll.dll!ExecuteHandler@20() + 0x24 bytes
ntdll.dll!_KiUserExceptionDispatcher@8() + 0xf bytes
KernelBase.dll!_DebugBreak@0() + 0x2 bytes
test_mixed.exe!01031009()
これは、最初のテストの呼び出しスタックです(「閉じる」と「デバッグ」を選択したダイアログ)。
ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 bytes
ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 bytes
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() + 0x8e bytes
kernel32.dll!_WaitForMultipleObjects@16() + 0x18 bytes
kernel32.dll!_WerpReportFaultInternal@8() + 0x124 bytes
kernel32.dll!_WerpReportFault@8() + 0x49 bytes
kernel32.dll!_BasepReportFault@8() + 0x1f bytes
kernel32.dll!_UnhandledExceptionFilter@4() + 0xe0 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x369cc bytes
ntdll.dll!@_EH4_CallFilterFunc@8() + 0x12 bytes
ntdll.dll!ExecuteHandler2@20() + 0x26 bytes
ntdll.dll!ExecuteHandler@20() + 0x24 bytes
ntdll.dll!_KiUserExceptionDispatcher@8() + 0xf bytes
KernelBase.dll!_DebugBreak@0() + 0x2 bytes
test_native.exe!00af1009()
違いはntdll.dll!Executehandler2@20から始まります。.net以外のアプリケーションでは、を呼び出しますntdll.dll!@_EH4_CallFilterFunc
。.netアプリケーションでは呼び出しclr.dll!__except_handler4
です。