使用以下简单的源代码(命名它测试.cpp):
#include <windows.h>
void main()
{
DebugBreak();
}
使用以下命令编译并链接:
cl /MD /c test.cpp
link /debug test.obj
如果测试.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函数,只是将它链接了进来。
现在快跑测试.EXE同样(在同一个64位Windows7系统上)。与上面显示的对话框不同,您可以看到:
为什么会这样?我怎样才能重新恢复以前的DebugBreak行为呢?
这可能是Windows7或64位特定的行为吗?
有一句话可以说明我为什么要使用DebugBreak:我们有一个自定义的assert框架(类似于John Robbin的《调试Windows应用程序》一书中的SuperAssert),我使用DebugBreak函数,这样如果出现问题,开发人员就可以跳转到调试器(或者打开一个新的调试器)。现在只有简单的弹出窗口,不可能再跳转到调试器了。
编辑:
这是第二个测试中的调用堆栈(简单对话框):
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!执行handler2@20。在非.net应用程序中,它调用
ntdll.dll!@_EH4_CallFilterFunc
. 在.net应用程序中是调用
clr.dll!__except_handler4
.