的DebugBreak的行为非托管和混合的(非托管+管理)应用程序之间不同?

StackOverflow https://stackoverflow.com/questions/3629783

  •  26-09-2019
  •  | 
  •  

以下面的简单的源(其命名为TEST.CPP):

#include <windows.h>

void main()
{
DebugBreak();
}

编译和链接使用下列命令这样的:

cl /MD /c test.cpp
link /debug test.obj

如果TEST.EXE现在运行(64位Windows 7系统上),你会得到如下对话框:

“的DebugBreak在非托管应用程序”

现在添加以下源文件(命名为测试2.cpp):

void hello()
{
}

和编译并且这连同第一源相连,这样的:

cl /MD /c       test.cpp
cl /MD /c /clr  test2.cpp
link test.obj test2.obj

请注意,我们甚至没有打电话问候功能,我们只是挂入。

现在(在相同的64位的Windows 7系统)再次运行TEST.EXE。而不是上面所示的对话框,你会得到这样的:

“的DebugBreak在混合模式应用”

显然,在.NET框架连接使的DebugBreak表现不同。 为什么是这样?而且我怎么能再次得到老的DebugBreak行为回来? 这是可能是Windows 7或64位的特定的行为?

一个侧面言论作出清楚,为什么我要使用的DebugBreak:我们有一个自定义的断言框架(由约翰·罗宾斯的调试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!Executehandler2@20。在non-.net应用程序调用ntdll.dll!@_EH4_CallFilterFunc。在.NET应用程序是电话clr.dll!__except_handler4

有帮助吗?

解决方案

我发现下面的页面上的溶液: HTTP://www.codeproject。 COM / KB /调试/ DebugBreakAnyway.aspx

而不是仅仅写的DebugBreak,你必须嵌入一个__try之间的DebugBreak呼叫/ __除了建筑,像这样的:

__try
   {
   DebugBreak();
   }
__except (UnhandledExceptionFilter(GetExceptionInformation()))
   {
   }

显然,UnhandledExceptionFilter的函数处理默认,这似乎在混合模式appliation被推翻了的DebugBreak例外。

现在你原来的对话框回来了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top