的DebugBreak行为非托管和混合(非托管+管理)应用程序之间的差异? [英] Behavior of DebugBreak differs between unmanaged and mixed (unmanaged+managed) application?

查看:306
本文介绍了的DebugBreak行为非托管和混合(非托管+管理)应用程序之间的差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Take the following simple source (name it test.cpp):

#include <windows.h>

void main()
{
DebugBreak();
}

编译并使用以下命令链接这样的:

Compile and link this using the following commands:

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

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

If TEST.EXE is now run (on a 64-bit Windows 7 system), you get the following dialog:

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

Now add the following source file (name it test2.cpp):

void hello()
{
}

和编译,并与第一源联系在一起这一点,像这样的:

And compile and link this together with the first source, like this:

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

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

Notice that we didn't even call the hello-function, we just linked it in.

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

Now run TEST.EXE again (on the same 64-bit Windows 7 system). Instead of the dialog shown above, you get this:

显然,连接在.NET Framework使的DebugBreak表现不同。 为什么是这样?我怎样才能得到旧的DebugBreak行为回来了? 这可能是Windows 7或64位特定的行为?

Apparently, linking in the .Net framework makes DebugBreak behave differently. Why is this? And how can I get the old DebugBreak behavior back again? Is this possibly a Windows 7 or 64-bit specific behavior?

一个侧面的话,使清楚,为什么我要使用的DebugBreak:我们有一个自定义的断言框架(有点像SuperAssert从约翰·罗宾的调试Windows应用程序的书),我使用的DebugBreak功能,使开发人员可以跳进调试器(或打开一个新的调试器),如果有一个问题。现在只有简单的弹出窗口并没有可能跳到调试了。

A side-remark to make clear why I want to use DebugBreak: we have a custom assert-framework (something like the SuperAssert from John Robbin's Debugging Windows Applications book), and I use the DebugBreak function so the developer can jump into the debugger (or open a new debugger) if there is a problem. Now there is only the simple popup and no possibility to jump to the debugger anymore.

作为一种替代解决方案,我可以进行分频零或写入无效的地址,但我觉得这是一个不太干净的解决方案。

As an alternative solution I could perform a divide-by-zero or a write to invalid address, but I find this a less clean solution.

编辑: 这是在第二测试调用堆栈(简单对话):

This is the call stack in the second test (the simple dialog):

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()   

这是第一次测试中的调用堆栈(对话框,选择关闭和调试):

This is the call stack in the first test (dialog with choices "close" and "debug"):

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

The difference starts in ntdll.dll!Executehandler2@20. In a non-.net application it calls ntdll.dll!@_EH4_CallFilterFunc. In a .net application is calls clr.dll!__except_handler4.

推荐答案

我发现下面的页面上的解决方案:的 HTTP://www.$c$cproject.com/KB/debug/DebugBreakAnyway.aspx

I found the solution on the following page: http://www.codeproject.com/KB/debug/DebugBreakAnyway.aspx.

,你必须嵌入之间的DebugBreak调用一个_ 尝试/ 的_except建设,像这样的:

Instead of just writing DebugBreak, you have to embed the DebugBreak call between a _try/_except construction, like this:

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

显然,UnhandledExceptionFilter的函数处理的DebugBreak异常默认情况下,这似乎在混合模式蒋云良被否决。

Apparently, the UnhandledExceptionFilter function handles the DebugBreak exception by default, which seems to be overruled in a mixed-mode appliation.

现在你再取回原来的对话框。

Now you get the original dialog back again.

这篇关于的DebugBreak行为非托管和混合(非托管+管理)应用程序之间的差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆