mirror of https://github.com/dotnet/runtime
Merge b00aba5e88
into 123627ba0f
This commit is contained in:
commit
f6ac207bfc
|
@ -37,6 +37,7 @@ FRAME_TYPE_NAME(DebuggerClassInitMarkFrame)
|
|||
FRAME_TYPE_NAME(DebuggerExitFrame)
|
||||
FRAME_TYPE_NAME(DebuggerU2MCatchHandlerFrame)
|
||||
FRAME_TYPE_NAME(ExceptionFilterFrame)
|
||||
FRAME_TYPE_NAME(UnhandledExceptionMarkerFrame)
|
||||
#ifdef FEATURE_INTERPRETER
|
||||
FRAME_TYPE_NAME(InterpreterFrame)
|
||||
#endif // FEATURE_INTERPRETER
|
||||
|
|
|
@ -295,6 +295,8 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
|
|||
|
||||
AppDomain *pCurDomain = SystemDomain::GetCurrentDomain();
|
||||
|
||||
UnhandledExceptionMarkerFrame unhandledExceptionMarkerFrame;
|
||||
|
||||
Thread *pThread = GetThreadNULLOk();
|
||||
if (pThread == NULL)
|
||||
{
|
||||
|
@ -305,6 +307,11 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
GCX_COOP();
|
||||
unhandledExceptionMarkerFrame.Push(pThread);
|
||||
}
|
||||
|
||||
INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
|
||||
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
|
||||
|
||||
|
@ -327,7 +334,6 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
|
|||
|
||||
{
|
||||
GCX_COOP();
|
||||
|
||||
PTRARRAYREF arguments = NULL;
|
||||
GCPROTECT_BEGIN(arguments);
|
||||
|
||||
|
@ -359,6 +365,11 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
|
|||
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
|
||||
UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
|
||||
|
||||
{
|
||||
GCX_COOP();
|
||||
unhandledExceptionMarkerFrame.Pop(pThread);
|
||||
}
|
||||
|
||||
#ifdef LOG_EXECUTABLE_ALLOCATOR_STATISTICS
|
||||
ExecutableAllocator::DumpHolderUsage();
|
||||
ExecutionManager::DumpExecutionManagerUsage();
|
||||
|
|
|
@ -2168,7 +2168,7 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id,
|
|||
// The sole purpose of having this frame is to tell the debugger that we have a catch handler here
|
||||
// which may swallow managed exceptions. The debugger needs this in order to send a
|
||||
// CatchHandlerFound (CHF) notification.
|
||||
DebuggerU2MCatchHandlerFrame catchFrame(true /* catchesAllExceptions */);
|
||||
DebuggerU2MCatchHandlerFrame catchFrame;
|
||||
|
||||
EX_TRY
|
||||
{
|
||||
|
|
|
@ -4013,16 +4013,17 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid
|
|||
// Check if there are any further managed frames on the stack or a catch for all exceptions in native code (marked by
|
||||
// DebuggerU2MCatchHandlerFrame with CatchesAllExceptions() returning true).
|
||||
// If not, the exception is unhandled.
|
||||
bool isNotHandledByRuntime =
|
||||
(pFrame == FRAME_TOP) ||
|
||||
(IsTopmostDebuggerU2MCatchHandlerFrame(pFrame) && !((DebuggerU2MCatchHandlerFrame*)pFrame)->CatchesAllExceptions())
|
||||
bool reportUnhandledException =
|
||||
((pFrame != FRAME_TOP) &&
|
||||
(pFrame->GetFrameIdentifier() == FrameIdentifier::UnhandledExceptionMarkerFrame) &&
|
||||
IsExceptionFromManagedCode(pTopExInfo->m_ptrs.ExceptionRecord))
|
||||
#ifdef HOST_UNIX
|
||||
// Don't allow propagating exceptions from managed to non-runtime native code
|
||||
|| isPropagatingToExternalNativeCode
|
||||
#endif
|
||||
;
|
||||
|
||||
if (isNotHandledByRuntime && IsExceptionFromManagedCode(pTopExInfo->m_ptrs.ExceptionRecord))
|
||||
if (reportUnhandledException)
|
||||
{
|
||||
EH_LOG((LL_INFO100, "SfiNext (pass %d): no more managed frames on the stack, the exception is unhandled", pTopExInfo->m_passNumber));
|
||||
if (pTopExInfo->m_passNumber == 1)
|
||||
|
|
|
@ -100,6 +100,9 @@
|
|||
// +-DebuggerU2MCatchHandlerFrame - marker frame to indicate that native code is going to catch and
|
||||
// | swallow a managed exception
|
||||
// |
|
||||
// +- UnhandledExceptionMarkerFrame - When exception handling passes through this frame,
|
||||
// | the exception is reported as unhandled.
|
||||
// |
|
||||
#ifdef DEBUGGING_SUPPORTED
|
||||
// +-FuncEvalFrame - frame for debugger function evaluation
|
||||
#endif // DEBUGGING_SUPPORTED
|
||||
|
@ -2077,15 +2080,13 @@ class DebuggerU2MCatchHandlerFrame : public Frame
|
|||
{
|
||||
public:
|
||||
#ifndef DACCESS_COMPILE
|
||||
DebuggerU2MCatchHandlerFrame(bool catchesAllExceptions) : Frame(FrameIdentifier::DebuggerU2MCatchHandlerFrame),
|
||||
m_catchesAllExceptions(catchesAllExceptions)
|
||||
DebuggerU2MCatchHandlerFrame() : Frame(FrameIdentifier::DebuggerU2MCatchHandlerFrame)
|
||||
{
|
||||
WRAPPER_NO_CONTRACT;
|
||||
Frame::Push();
|
||||
}
|
||||
|
||||
DebuggerU2MCatchHandlerFrame(Thread * pThread, bool catchesAllExceptions) : Frame(FrameIdentifier::DebuggerU2MCatchHandlerFrame),
|
||||
m_catchesAllExceptions(catchesAllExceptions)
|
||||
DebuggerU2MCatchHandlerFrame(Thread * pThread) : Frame(FrameIdentifier::DebuggerU2MCatchHandlerFrame)
|
||||
{
|
||||
WRAPPER_NO_CONTRACT;
|
||||
Frame::Push(pThread);
|
||||
|
@ -2097,16 +2098,19 @@ public:
|
|||
LIMITED_METHOD_DAC_CONTRACT;
|
||||
return TT_U2M;
|
||||
}
|
||||
};
|
||||
|
||||
bool CatchesAllExceptions()
|
||||
typedef DPTR(class UnhandledExceptionMarkerFrame) PTR_UnhandledExceptionMarkerFrame;
|
||||
|
||||
// When exception handling passes through this frame, the exception is reported as unhandled.
|
||||
class UnhandledExceptionMarkerFrame : public Frame
|
||||
{
|
||||
public:
|
||||
#ifndef DACCESS_COMPILE
|
||||
UnhandledExceptionMarkerFrame() : Frame(FrameIdentifier::UnhandledExceptionMarkerFrame)
|
||||
{
|
||||
LIMITED_METHOD_DAC_CONTRACT;
|
||||
return m_catchesAllExceptions;
|
||||
}
|
||||
|
||||
private:
|
||||
// The catch handled marked by the DebuggerU2MCatchHandlerFrame catches all exceptions.
|
||||
bool m_catchesAllExceptions;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Frame for the Reverse PInvoke (i.e. UnmanagedCallersOnlyAttribute).
|
||||
|
|
|
@ -355,18 +355,15 @@ namespace InteropLibImports
|
|||
return TryInvokeICustomQueryInterfaceResult::FailedToInvoke;
|
||||
}
|
||||
|
||||
// Switch to Cooperative mode since object references
|
||||
// are being manipulated and the catchFrame needs that so that it can push
|
||||
// itself to the explicit frame stack.
|
||||
GCX_COOP();
|
||||
// Indicate to the debugger and exception handling that managed exceptions are being caught
|
||||
// here.
|
||||
DebuggerU2MCatchHandlerFrame catchFrame(true /* catchesAllExceptions */);
|
||||
|
||||
HRESULT hr;
|
||||
auto result = TryInvokeICustomQueryInterfaceResult::FailedToInvoke;
|
||||
EX_TRY_THREAD(CURRENT_THREAD)
|
||||
{
|
||||
// Switch to Cooperative mode since object references
|
||||
// are being manipulated and the catchFrame needs that so that it can push
|
||||
// itself to the explicit frame stack.
|
||||
GCX_COOP();
|
||||
|
||||
struct
|
||||
{
|
||||
OBJECTREF objRef;
|
||||
|
@ -384,8 +381,6 @@ namespace InteropLibImports
|
|||
}
|
||||
EX_CATCH_HRESULT(hr);
|
||||
|
||||
catchFrame.Pop();
|
||||
|
||||
// Assert valid value.
|
||||
_ASSERTE(TryInvokeICustomQueryInterfaceResult::Min <= result
|
||||
&& result <= TryInvokeICustomQueryInterfaceResult::Max);
|
||||
|
|
|
@ -10525,12 +10525,8 @@ bool CEEInfo::runWithErrorTrap(void (*function)(void*), void* param)
|
|||
|
||||
bool success = true;
|
||||
|
||||
GCX_COOP();
|
||||
DebuggerU2MCatchHandlerFrame catchFrame(true /* catchesAllExceptions */);
|
||||
|
||||
EX_TRY
|
||||
{
|
||||
GCX_PREEMP();
|
||||
function(param);
|
||||
}
|
||||
EX_CATCH
|
||||
|
@ -10540,8 +10536,6 @@ bool CEEInfo::runWithErrorTrap(void (*function)(void*), void* param)
|
|||
}
|
||||
EX_END_CATCH
|
||||
|
||||
catchFrame.Pop();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
@ -7001,7 +7001,10 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
|
|||
// The sole purpose of having this frame is to tell the debugger that we have a catch handler here
|
||||
// which may swallow managed exceptions. The debugger needs this in order to send a
|
||||
// CatchHandlerFound (CHF) notification.
|
||||
DebuggerU2MCatchHandlerFrame catchFrame(false /* catchesAllExceptions */);
|
||||
DebuggerU2MCatchHandlerFrame catchFrame(pThread);
|
||||
|
||||
UnhandledExceptionMarkerFrame unhandledExceptionMarkerFrame;
|
||||
unhandledExceptionMarkerFrame.Push(pThread);
|
||||
|
||||
TryParam param(pCallState);
|
||||
param.pFrame = &catchFrame;
|
||||
|
@ -7056,7 +7059,8 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
|
|||
}
|
||||
PAL_FINALLY
|
||||
{
|
||||
catchFrame.Pop();
|
||||
unhandledExceptionMarkerFrame.Pop(pThread);
|
||||
catchFrame.Pop(pThread);
|
||||
}
|
||||
PAL_ENDTRY;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue