Skip to content

Commit

Permalink
Exception interception fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
janvorli committed Dec 5, 2023
1 parent fa751d1 commit 54f4b25
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ internal static unsafe partial bool RhpCallFilterFunclet(
#pragma warning restore CS8500

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "EHEnumInitFromStackFrameIterator")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static unsafe partial bool RhpEHEnumInitFromStackFrameIterator(ref StackFrameIterator pFrameIter, byte** pMethodStartAddress, void* pEHEnum);
//[return: MarshalAs(UnmanagedType.Bool)]
internal static unsafe partial int RhpEHEnumInitFromStackFrameIterator(ref StackFrameIterator pFrameIter, byte** pMethodStartAddress, void* pEHEnum);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "EHEnumNext")]
[return: MarshalAs(UnmanagedType.Bool)]
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/debug/ee/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6142,6 +6142,12 @@ bool DebuggerStepper::IsInterestingFrame(FrameInfo * pFrame)
{
LIMITED_METHOD_CONTRACT;

// Ignore managed exception handling frames
if (pFrame->md != NULL && pFrame->md->GetMethodTable() == g_pEHClass)
{
return false;
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,11 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn
// without a catch handler or propagation callback.
Debug.Assert(pCatchHandler != null || pReversePInvokePropagationCallback != IntPtr.Zero || unwoundReversePInvoke, "We should have a handler if we're starting the second pass");

if (pCatchHandler == (byte*)2)
{
pCatchHandler = null;
}

// ------------------------------------------------
//
// Second pass
Expand Down Expand Up @@ -808,11 +813,20 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn
)
{
// invoke only a partial second-pass here...
InvokeSecondPass(ref exInfo, startIdx, catchingTryRegionIdx);
int res = InvokeSecondPass(ref exInfo, startIdx, catchingTryRegionIdx);
if (res == 2)
{
pCatchHandler = null;
}
break;
}

InvokeSecondPass(ref exInfo, startIdx);
int res2 = InvokeSecondPass(ref exInfo, startIdx);
if (res2 == 2)
{
pCatchHandler = null;
break;
}
}

#if FEATURE_OBJCMARSHAL
Expand Down Expand Up @@ -893,8 +907,16 @@ private static bool FindFirstPassHandler(object exception, uint idxStart,

EHEnum ehEnum;
byte* pbMethodStartAddress;
if (!InternalCalls.RhpEHEnumInitFromStackFrameIterator(ref frameIter, &pbMethodStartAddress, &ehEnum))
int ehEnumState = InternalCalls.RhpEHEnumInitFromStackFrameIterator(ref frameIter, &pbMethodStartAddress, &ehEnum);
if (ehEnumState == 0)
{
return false;
}
else if (ehEnumState == 2)
{
pHandler = (byte*)2;
return true;
}

byte* pbControlPC = frameIter.ControlPC;

Expand All @@ -906,6 +928,13 @@ private static bool FindFirstPassHandler(object exception, uint idxStart,
RhEHClause ehClause;
for (uint curIdx = 0; InternalCalls.RhpEHEnumNext(&ehEnum, &ehClause); curIdx++)
{
RhEHClauseKind clauseKind = ehClause._clauseKind;

// if (clauseKind == RhEHClauseKind.RH_EH_CLAUSE_UNUSED)
// {
// // Debugger interception
// return true;
// }
//
// Skip to the starting try region. This is used by collided unwinds and rethrows to pickup where
// the previous dispatch left off.
Expand All @@ -932,8 +961,6 @@ private static bool FindFirstPassHandler(object exception, uint idxStart,
idxStart = MaxTryRegionIdx;
}

RhEHClauseKind clauseKind = ehClause._clauseKind;

if (((clauseKind != RhEHClauseKind.RH_EH_CLAUSE_TYPED) &&
(clauseKind != RhEHClauseKind.RH_EH_CLAUSE_FILTER))
|| !ehClause.ContainsCodeOffset(codeOffset))
Expand Down Expand Up @@ -1043,16 +1070,19 @@ private static bool ShouldTypedClauseCatchThisException(object exception, Method
#endif
}

private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart)
private static int InvokeSecondPass(ref ExInfo exInfo, uint idxStart)
{
InvokeSecondPass(ref exInfo, idxStart, MaxTryRegionIdx);
return InvokeSecondPass(ref exInfo, idxStart, MaxTryRegionIdx);
}
private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart, uint idxLimit)
private static int InvokeSecondPass(ref ExInfo exInfo, uint idxStart, uint idxLimit)
{
EHEnum ehEnum;
byte* pbMethodStartAddress;
if (!InternalCalls.RhpEHEnumInitFromStackFrameIterator(ref exInfo._frameIter, &pbMethodStartAddress, &ehEnum))
return;
int ehEnumState = InternalCalls.RhpEHEnumInitFromStackFrameIterator(ref exInfo._frameIter, &pbMethodStartAddress, &ehEnum);
if (ehEnumState != 1)
{
return ehEnumState;
}

byte* pbControlPC = exInfo._frameIter.ControlPC;

Expand Down Expand Up @@ -1125,6 +1155,8 @@ private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart, uint idxL
#endif // NATIVEAOT
exInfo._idxCurClause = MaxTryRegionIdx;
}

return 1;
}

#if NATIVEAOT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ internal static int RhEndNoGCRegion()

[RuntimeImport(Redhawk.BaseName, "RhpEHEnumInitFromStackFrameIterator")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe bool RhpEHEnumInitFromStackFrameIterator(ref StackFrameIterator pFrameIter, byte** pMethodStartAddress, void* pEHEnum);
internal static extern unsafe int RhpEHEnumInitFromStackFrameIterator(ref StackFrameIterator pFrameIter, byte** pMethodStartAddress, void* pEHEnum);

[RuntimeImport(Redhawk.BaseName, "RhpEHEnumNext")]
[MethodImpl(MethodImplOptions.InternalCall)]
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/nativeaot/Runtime/EHHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
#include "MethodTable.h"
#include "MethodTable.inl"

COOP_PINVOKE_HELPER(FC_BOOL_RET, RhpEHEnumInitFromStackFrameIterator, (
COOP_PINVOKE_HELPER(int32_t, RhpEHEnumInitFromStackFrameIterator, (
StackFrameIterator* pFrameIter, void ** pMethodStartAddressOut, EHEnum* pEHEnum))
{
ICodeManager * pCodeManager = pFrameIter->GetCodeManager();
pEHEnum->m_pCodeManager = pCodeManager;

FC_RETURN_BOOL(pCodeManager->EHEnumInit(pFrameIter->GetMethodInfo(), pMethodStartAddressOut, &pEHEnum->m_state));
return pCodeManager->EHEnumInit(pFrameIter->GetMethodInfo(), pMethodStartAddressOut, &pEHEnum->m_state) ? 1 : 0;
}

COOP_PINVOKE_HELPER(FC_BOOL_RET, RhpEHEnumNext, (EHEnum* pEHEnum, EHClause* pEHClause))
Expand Down
Loading

0 comments on commit 54f4b25

Please sign in to comment.