@@ -325,25 +325,31 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, LPCWSTR errorSource
325325{
326326 WRAPPER_NO_CONTRACT;
327327
328- static Thread *const FatalErrorNotSeenYet = nullptr ;
329- static Thread *const FatalErrorLoggingFinished = reinterpret_cast <Thread *>(1 );
328+ static size_t s_pCrashingThreadID;
330329
331- static Thread *volatile s_pCrashingThread = FatalErrorNotSeenYet;
330+ size_t currentThreadID;
331+ #ifndef TARGET_UNIX
332+ currentThreadID = GetCurrentThreadId ();
333+ #else
334+ currentThreadID = PAL_GetCurrentOSThreadId ();
335+ #endif
332336
333- Thread *pThread = GetThreadNULLOk ();
334- Thread *pPreviousThread = InterlockedCompareExchangeT<Thread *>(&s_pCrashingThread, pThread, FatalErrorNotSeenYet);
337+ size_t previousThreadID = InterlockedCompareExchangeT<size_t >(&s_pCrashingThreadID, currentThreadID, 0 );
335338
336- if (pPreviousThread == pThread)
337- {
338- PrintToStdErrA (" Fatal error while logging another fatal error.\n " );
339- return ;
340- }
341- else if (pPreviousThread != nullptr )
339+ // Let the first crashing thread take care of the reporting.
340+ if (previousThreadID != 0 )
342341 {
343- GCX_PREEMP (); // Avoid blocking other threads that may be trying to suspend the runtime
344- while (s_pCrashingThread != FatalErrorLoggingFinished)
342+ if (previousThreadID == currentThreadID)
343+ {
344+ PrintToStdErrA (" Fatal error while logging another fatal error.\n " );
345+ }
346+ else
345347 {
346- ClrSleepEx (50 , /* bAlertable*/ FALSE );
348+ // Switch to preemptive mode to avoid blocking the crashing thread. It may try to suspend the runtime
349+ // for GC during the stacktrace reporting.
350+ GCX_PREEMP ();
351+
352+ ClrSleepEx (INFINITE, /* bAlertable*/ FALSE );
347353 }
348354 return ;
349355 }
@@ -379,9 +385,10 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, LPCWSTR errorSource
379385
380386 PrintToStdErrA (" \n " );
381387
388+ Thread* pThread = GetThreadNULLOk ();
382389 if (pThread && errorSource == NULL )
383390 {
384- LogCallstackForLogWorker (GetThread () );
391+ LogCallstackForLogWorker (pThread );
385392
386393 if (argExceptionString != NULL ) {
387394 PrintToStdErrW (argExceptionString);
@@ -392,8 +399,6 @@ void LogInfoForFatalError(UINT exitCode, LPCWSTR pszMessage, LPCWSTR errorSource
392399 {
393400 }
394401 EX_END_CATCH (SwallowAllExceptions)
395-
396- InterlockedCompareExchangeT<Thread *>(&s_pCrashingThread, FatalErrorLoggingFinished, pThread);
397402}
398403
399404// This starts FALSE and then converts to true if HandleFatalError has ever been called by a GC thread
0 commit comments