Verhalten unterscheidet zwischen nicht verwalteten Debugbreak und gemischten (unmanaged + verwaltet) Anwendung?

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

  •  26-09-2019
  •  | 
  •  

Frage

Nehmen Sie die folgenden einfachen Quelle (name it test.cpp):

#include <windows.h>

void main()
{
DebugBreak();
}

kompilieren und verknüpfen diese mit den folgenden Befehlen:

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

Wenn TEST.EXE jetzt ausgeführt wird (auf einem 64-Bit-Windows-7-System), den folgenden Dialog erhalten:

Debugbreak in nicht verwalteten Anwendung

Nun fügen Sie die folgende Quelldatei (Name es test2.cpp):

void hello()
{
}

Und kompilieren und verknüpfen diese zusammen mit der ersten Quelle, wie diese:

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

Beachten Sie, dass wir die hallo-Funktion nicht einmal angerufen haben, wir verknüpfen es nur in.

Jetzt läuft TEST.EXE wieder (auf dem gleichen 64-Bit-Windows-7-System). Statt der Dialog oben gezeigt, können Sie diese:

Debugbreak in Mixed-Mode-Anwendung

Offenbar in .NET Framework Verknüpfung macht Debugbreak verhalten sich anders. Warum ist das? Und wie kann ich wieder das alte Verhalten Debugbreak zurück? Ist dies möglicherweise ein Windows 7 oder 64-Bit-spezifisches Verhalten?

Eine Neben Bemerkung deutlich machen, warum ich will Debugbreak verwenden: wir haben einen eigenen assert-Rahmen (so etwas wie die SuperAssert von John Robbins Debuggen von Windows-Anwendungen Buch), und ich verwende die Debugbreak-Funktion, so der Entwickler in springen der Debugger (oder öffnen Sie ein neues Debugger), wenn es ein Problem gibt. Jetzt gibt es nur die einfache Popup und keine Möglichkeit mehr zum Debugger zu springen.

Als alternative Lösung I eine Division durch Null oder einen Schreibvorgang zu ungültiger Adresse durchführen könnte, aber ich dieses eine weniger saubere Lösung finden.

EDIT: Dies ist den Call-Stack im zweiten Test (der einfache 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()   

Dies ist der Call-Stack im ersten Test (Dialog mit Auswahl "close" und "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()  

Der Unterschied beginnt in ntdll.dll!Executehandler2@20. In einer non-.net Anwendung ruft es ntdll.dll!@_EH4_CallFilterFunc. In einer .NET-Anwendung ist Anrufe clr.dll!__except_handler4.

War es hilfreich?

Lösung

fand ich die Lösung auf der folgenden Seite: http: //www.codeproject. com / KB / debug / DebugBreakAnyway.aspx .

Statt nur Debugbreak schreiben, haben Sie die Debugbreak Anruf zwischen einem __try / __ ausgenommen Bau einzubetten, wie folgt aus:

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

Offenbar die UnhandledExceptionFilter Funktion Griffe die Debugbreak Ausnahme von Standard, die in einem gemischten Modus appliation außer Kraft gesetzt zu sein scheint.

Sie nun den Original-Dialog wieder umkehren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top