Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 17 additions & 128 deletions src/coreclr/vm/dispatchinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1648,110 +1648,6 @@ void DispatchInfo::InvokeMemberWorker(DispatchMemberInfo* pDispMemberInfo,
MarshalReturnValueManagedToNative(pDispMemberInfo, &pObjs->RetVal, pVarRes);
}

void DispatchInfo::InvokeMemberDebuggerWrapper(
DispatchMemberInfo* pDispMemberInfo,
InvokeObjects* pObjs,
int NumParams,
int NumArgs,
int NumNamedArgs,
int& NumByrefArgs,
int& iSrcArg,
DISPID id,
DISPPARAMS* pdp,
VARIANT* pVarRes,
WORD wFlags,
LCID lcid,
DISPID* pSrcArgNames,
VARIANT* pSrcArgs,
OBJECTHANDLE* aByrefStaticArrayBackupObjHandle,
int* pManagedMethodParamIndexMap,
VARIANT** aByrefArgOleVariant,
Frame * pFrame)

{
// Use static contracts b/c we have SEH.
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;
STATIC_CONTRACT_MODE_ANY;

// @todo - we have a PAL_TRY/PAL_EXCEPT here as a general (cross-platform) way to get a 1st-pass
// filter. If that's bad perf, we could inline an FS:0 handler for x86-only; and then inline
// both this wrapper and the main body.

struct Param : public NotifyOfCHFFilterWrapperParam
{
DispatchInfo* pThis;
DispatchMemberInfo* pDispMemberInfo;
InvokeObjects* pObjs;
int NumParams;
int NumArgs;
int NumNamedArgs;
int& NumByrefArgs;
int& iSrcArg;
DISPID id;
DISPPARAMS* pdp;
VARIANT* pVarRes;
WORD wFlags;
LCID lcid;
DISPID* pSrcArgNames;
VARIANT* pSrcArgs;
OBJECTHANDLE* aByrefStaticArrayBackupObjHandle;
int* pManagedMethodParamIndexMap;
VARIANT** aByrefArgOleVariant;

Param(int& _NumByrefArgs, int& _iSrcArg)
: NumByrefArgs(_NumByrefArgs), iSrcArg(_iSrcArg)
{}
} param(NumByrefArgs, iSrcArg);

param.pFrame = GetThread()->GetFrame(); // Inherited from NotifyOfCHFFilterWrapperParam
param.pThis = this;
param.pDispMemberInfo = pDispMemberInfo;
param.pObjs = pObjs;
param.NumParams = NumParams;
param.NumArgs = NumArgs;
param.NumNamedArgs = NumNamedArgs;
//param.NumByrefArgs = NumByrefArgs;
//param.iSrcArg = iSrcArg;
param.id = id;
param.pdp = pdp;
param.pVarRes = pVarRes;
param.wFlags = wFlags;
param.lcid = lcid;
param.pSrcArgNames = pSrcArgNames;
param.pSrcArgs = pSrcArgs;
param.aByrefStaticArrayBackupObjHandle = aByrefStaticArrayBackupObjHandle;
param.pManagedMethodParamIndexMap = pManagedMethodParamIndexMap;
param.aByrefArgOleVariant = aByrefArgOleVariant;

PAL_TRY(Param *, pParam, &param)
{
pParam->pThis->InvokeMemberWorker(pParam->pDispMemberInfo,
pParam->pObjs,
pParam->NumParams,
pParam->NumArgs,
pParam->NumNamedArgs,
pParam->NumByrefArgs,
pParam->iSrcArg,
pParam->id,
pParam->pdp,
pParam->pVarRes,
pParam->wFlags,
pParam->lcid,
pParam->pSrcArgNames,
pParam->pSrcArgs,
pParam->aByrefStaticArrayBackupObjHandle,
pParam->pManagedMethodParamIndexMap,
pParam->aByrefArgOleVariant);
}
PAL_EXCEPT_FILTER(NotifyOfCHFFilterWrapper)
{
// Should never reach here b/c handler should always continue search.
_ASSERTE(false);
}
PAL_ENDTRY
}

// Helper method that invokes the member with the specified DISPID.
HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pVarRes, EXCEPINFO *pei, IServiceProvider *pspCaller, unsigned int *puArgErr)
{
Expand Down Expand Up @@ -1975,39 +1871,32 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id,
// Invoke the method.
//

// 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 */);

EX_TRY
{
InvokeMemberDebuggerWrapper(pDispMemberInfo,
&Objs,
NumParams,
NumArgs,
NumNamedArgs,
NumByrefArgs,
iSrcArg,
id,
pdp,
pVarRes,
wFlags,
lcid,
pSrcArgNames,
pSrcArgs,
aByrefStaticArrayBackupObjHandle,
pManagedMethodParamIndexMap,
aByrefArgOleVariant,
&catchFrame);
InvokeMemberWorker(pDispMemberInfo,
&Objs,
NumParams,
NumArgs,
NumNamedArgs,
NumByrefArgs,
iSrcArg,
id,
pdp,
pVarRes,
wFlags,
lcid,
pSrcArgNames,
pSrcArgs,
aByrefStaticArrayBackupObjHandle,
pManagedMethodParamIndexMap,
aByrefArgOleVariant);
}
EX_CATCH
{
pThrowable = GET_THROWABLE();
RethrowTerminalExceptions();
}
EX_END_CATCH
catchFrame.Pop();

if (pThrowable != NULL)
{
Expand Down
19 changes: 0 additions & 19 deletions src/coreclr/vm/dispatchinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,25 +262,6 @@ class DispatchInfo
// Helper method that invokes the member with the specified DISPID.
HRESULT InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pVarRes, EXCEPINFO *pei, IServiceProvider *pspCaller, unsigned int *puArgErr);

void InvokeMemberDebuggerWrapper(DispatchMemberInfo* pDispMemberInfo,
InvokeObjects* pObjs,
int NumParams,
int NumArgs,
int NumNamedArgs,
int& NumByrefArgs,
int& iSrcArg,
DISPID id,
DISPPARAMS* pdp,
VARIANT* pVarRes,
WORD wFlags,
LCID lcid,
DISPID* pSrcArgNames,
VARIANT* pSrcArgs,
OBJECTHANDLE* aByrefStaticArrayBackupObjHandle,
int* pManagedMethodParamIndexMap,
VARIANT** aByrefArgOleVariant,
Frame * pFrame);

void InvokeMemberWorker(DispatchMemberInfo* pDispMemberInfo,
InvokeObjects* pObjs,
int NumParams,
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4195,12 +4195,11 @@ CLR_BOOL SfiNextWorker(StackFrameIterator* pThis, uint* uExCollideClauseIdx, CLR
{
pFrame = pThis->m_crawl.GetFrame();

// 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).
// Check if there are any further managed frames on the stack.
// If not, the exception is unhandled.
bool isNotHandledByRuntime =
(pFrame == FRAME_TOP) ||
(IsTopmostDebuggerU2MCatchHandlerFrame(pFrame) && !((DebuggerU2MCatchHandlerFrame*)pFrame)->CatchesAllExceptions())
IsTopmostDebuggerU2MCatchHandlerFrame(pFrame)
#ifdef HOST_UNIX
// Don't allow propagating exceptions from managed to non-runtime native code
|| isPropagatingToExternalNativeCode
Expand Down
15 changes: 2 additions & 13 deletions src/coreclr/vm/frames.h
Original file line number Diff line number Diff line change
Expand Up @@ -2010,15 +2010,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);
Expand All @@ -2039,15 +2037,6 @@ class DebuggerU2MCatchHandlerFrame : public Frame
}
#endif // DACCESS_COMPILE

bool CatchesAllExceptions()
{
LIMITED_METHOD_DAC_CONTRACT;
return m_catchesAllExceptions;
}

private:
// The catch handled marked by the DebuggerU2MCatchHandlerFrame catches all exceptions.
bool m_catchesAllExceptions;
};

// Frame for the Reverse PInvoke (i.e. UnmanagedCallersOnlyAttribute).
Expand Down
18 changes: 10 additions & 8 deletions src/coreclr/vm/interoplibinterface_comwrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,37 +325,39 @@ namespace InteropLibImports
}

// 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.
// are being manipulated.
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;

// While ComWrappers.CallICustomQueryInterface itself will not throw,
// it's possible that the runtime may throw an exception (such as allocation failure/OOM)
// when jitting the method. As we may be called from unmanaged code,
// we need to catch such an exception.
EX_TRY_THREAD(CURRENT_THREAD)
{
struct
{
OBJECTREF objRef;
EXCEPTIONREF exceptionRef;
} gc;
Comment on lines 340 to 344
gc.objRef = NULL;

GCPROTECT_BEGIN(gc);

// Get the target of the external object's reference.
::OBJECTHANDLE objectHandle = static_cast<::OBJECTHANDLE>(handle);
gc.objRef = ObjectFromHandle(objectHandle);

UnmanagedCallersOnlyCaller callICustomQueryInterface(METHOD__COMWRAPPERS__CALL_ICUSTOMQUERYINTERFACE);
result = (TryInvokeICustomQueryInterfaceResult)callICustomQueryInterface.InvokeThrowing_Ret<INT32>(&gc.objRef, &iid, obj);
result = (TryInvokeICustomQueryInterfaceResult)callICustomQueryInterface.InvokeDirect_Ret<INT32>(&gc.objRef, &iid, obj, &gc.exceptionRef);
hr = gc.exceptionRef == NULL ? S_OK : gc.exceptionRef->GetHResult();

GCPROTECT_END();
}
EX_CATCH_HRESULT(hr);

catchFrame.Pop();

// Assert valid value.
_ASSERTE(TryInvokeICustomQueryInterfaceResult::Min <= result
&& result <= TryInvokeICustomQueryInterfaceResult::Max);
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10960,7 +10960,6 @@ bool CEEInfo::runWithErrorTrap(void (*function)(void*), void* param)
bool success = true;

GCX_COOP();
DebuggerU2MCatchHandlerFrame catchFrame(true /* catchesAllExceptions */);

EX_TRY
{
Expand All @@ -10974,8 +10973,6 @@ bool CEEInfo::runWithErrorTrap(void (*function)(void*), void* param)
}
EX_END_CATCH

catchFrame.Pop();

return success;
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5927,7 +5927,7 @@ 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;

TryParam param(pCallState);
param.pFrame = &catchFrame;
Expand Down
Loading