2010-09-02 168 views
1

看看下面的简单源(命名为TEST.CPP):DebugBreak的行为在非托管和混合(非托管+托管)应用程序之间有所不同?

#include <windows.h> 

void main() 
{ 
DebugBreak(); 
} 

编译并使用以下命令链接此:

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

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

DebugBreak in unmanaged application

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

void hello() 
{ 
} 

和编译,并与第一源链接在一起这一点,就像这样:

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

请注意,我们甚至没有打电话问候功能,我们只是它挂钩英寸

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

DebugBreak in mixed-mode application

显然,在.NET Framework链接使得的DebugBreak表现不同。 这是为什么?我怎么能再次得到旧的DebugBreak行为? 这可能是Windows 7或64位特定行为?我使用DebugBreak:我们有一个自定义的assert-framework(类似于John Robbin的调试Windows应用程序手册中的SuperAssert),我使用DebugBreak函数,这样开发人员就可以跳转进入调试器(或打开一个新的调试器),如果有问题。现在只有简单的弹出窗口,不再可以跳转到调试器了。

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

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

[email protected]() + 0x12 bytes 
[email protected]() + 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 
[email protected]() + 0x71111 bytes 
[email protected][email protected]() + 0x12 bytes 
msvcr100_clr0400.dll!__except_handler4_common() + 0x7f bytes 
clr.dll!__except_handler4() + 0x20 bytes 
[email protected]() + 0x26 bytes  
[email protected]() + 0x24 bytes 
[email protected]() + 0xf bytes 
[email protected]() + 0x2 bytes 
test_mixed.exe!01031009() 

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

[email protected]() + 0x15 bytes 
[email protected]() + 0x15 bytes 
[email protected]() + 0x8e bytes 
[email protected]() + 0x18 bytes 
[email protected]() + 0x124 bytes  
[email protected]() + 0x49 bytes 
[email protected]() + 0x1f bytes  
[email protected]() + 0xe0 bytes  
[email protected]() + 0x369cc bytes  
[email protected][email protected]() + 0x12 bytes  
[email protected]() + 0x26 bytes  
[email protected]() + 0x24 bytes 
[email protected]() + 0xf bytes 
[email protected]() + 0x2 bytes 
test_native.exe!00af1009() 

区别开始于[email protected]。在非.NET应用程序中,它调用[email protected]_EH4_CallFilterFunc。在.net应用程序中调用clr.dll!__except_handler4

回答

2

我在下页找到了解决方案:http://www.codeproject.com/KB/debug/DebugBreakAnyway.aspx

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

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

显然,UnhandledExceptionFilter的函数处理默认的DebugBreak例外,这似乎是在混合模式申请中被否决。

现在您再次获得原始对话框。