Skip to content

Commit

Permalink
Store unhandled exception info on stack in Native AOT (#84871)
Browse files Browse the repository at this point in the history
Allocates a span on the stack to hold the ToString of the exception, as well as a CrashRecord which contains a unique cookie that can be used to find the exception info.

Fixes #84636
  • Loading branch information
agocke committed Apr 27, 2023
1 parent 75c855e commit 5d65dd6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 449 deletions.
58 changes: 1 addition & 57 deletions src/coreclr/nativeaot/Runtime/threadstore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,60 +505,4 @@ void ThreadStore::SaveCurrentThreadOffsetForDAC()
{
}

#endif // _WIN32


#ifndef DACCESS_COMPILE

// internal static extern unsafe bool RhGetExceptionsForCurrentThread(Exception[] outputArray, out int writtenCountOut);
COOP_PINVOKE_HELPER(FC_BOOL_RET, RhGetExceptionsForCurrentThread, (Array* pOutputArray, int32_t* pWrittenCountOut))
{
FC_RETURN_BOOL(GetThreadStore()->GetExceptionsForCurrentThread(pOutputArray, pWrittenCountOut));
}

bool ThreadStore::GetExceptionsForCurrentThread(Array* pOutputArray, int32_t* pWrittenCountOut)
{
int32_t countWritten = 0;
Object** pArrayElements;
Thread * pThread = GetCurrentThread();

for (PTR_ExInfo pInfo = pThread->m_pExInfoStackHead; pInfo != NULL; pInfo = pInfo->m_pPrevExInfo)
{
if (pInfo->m_exception == NULL)
continue;

countWritten++;
}

// No input array provided, or it was of the wrong kind. We'll fill out the count and return false.
if ((pOutputArray == NULL) || (pOutputArray->get_EEType()->RawGetComponentSize() != POINTER_SIZE))
goto Error;

// Input array was not big enough. We don't even partially fill it.
if (pOutputArray->GetArrayLength() < (uint32_t)countWritten)
goto Error;

*pWrittenCountOut = countWritten;

// Success, but nothing to report.
if (countWritten == 0)
return true;

pArrayElements = (Object**)pOutputArray->GetArrayData();
for (PTR_ExInfo pInfo = pThread->m_pExInfoStackHead; pInfo != NULL; pInfo = pInfo->m_pPrevExInfo)
{
if (pInfo->m_exception == NULL)
continue;

*pArrayElements = pInfo->m_exception;
pArrayElements++;
}

RhpBulkWriteBarrier(pArrayElements, countWritten * POINTER_SIZE);
return true;

Error:
*pWrittenCountOut = countWritten;
return false;
}
#endif // DACCESS_COMPILE
#endif // _WIN32
1 change: 0 additions & 1 deletion src/coreclr/nativeaot/Runtime/threadstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class ThreadStore
#else
static PTR_Thread GetThreadFromTEB(TADDR pvTEB);
#endif
bool GetExceptionsForCurrentThread(Array* pOutputArray, int32_t* pWrittenCountOut);

void Destroy();
void SuspendAllThreads(bool waitForGCEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,10 +599,6 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe
internal static extern unsafe int RhGetModuleFileName(IntPtr moduleHandle, out char* moduleName);
#endif

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhGetExceptionsForCurrentThread")]
internal static extern unsafe bool RhGetExceptionsForCurrentThread(Exception[] outputArray, out int writtenCountOut);

// returns the previous value.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhSetErrorInfoBuffer")]
Expand Down
Loading

0 comments on commit 5d65dd6

Please sign in to comment.