summaryrefslogtreecommitdiff
path: root/src/vm/ceemain.cpp
diff options
context:
space:
mode:
authorSung Yoon Whang <suwhang@microsoft.com>2018-04-20 23:05:00 -0700
committerJan Kotas <jkotas@microsoft.com>2018-04-20 23:05:00 -0700
commit1c8c59387cb5989b5494f346c8127feb9dff27bc (patch)
treed73a23d4af1044c445f21cdbb06321071e810e10 /src/vm/ceemain.cpp
parent69e3ed349763a427f5b47513ec48484dbbed7397 (diff)
downloadcoreclr-1c8c59387cb5989b5494f346c8127feb9dff27bc.tar.gz
coreclr-1c8c59387cb5989b5494f346c8127feb9dff27bc.tar.bz2
coreclr-1c8c59387cb5989b5494f346c8127feb9dff27bc.zip
Disable GC Coop mode switching during fatal error handling during GC exception (#17710)
Diffstat (limited to 'src/vm/ceemain.cpp')
-rw-r--r--src/vm/ceemain.cpp58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index 1d14293441..b8c0adc363 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -2923,6 +2923,7 @@ static void TerminateIPCManager(void)
// Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
// copy culture name into szBuffer and return length
// ---------------------------------------------------------------------------
+extern BOOL g_fFatalErrorOccuredOnGCThread;
static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
{
CONTRACTL
@@ -2945,7 +2946,23 @@ static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
Thread * pThread = GetThread();
- if (pThread != NULL) {
+ // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
+ // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
+ // getting localized with a non-default thread-specific culture.
+ // A canonical stack trace that gets here is a fatal error in the GC that comes through:
+ // coreclr.dll!GetThreadUICultureNames
+ // coreclr.dll!CCompRC::LoadLibraryHelper
+ // coreclr.dll!CCompRC::LoadLibrary
+ // coreclr.dll!CCompRC::GetLibrary
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResource
+ // coreclr.dll!EventReporter::EventReporter
+ // coreclr.dll!EEPolicy::LogFatalError
+ // coreclr.dll!EEPolicy::HandleFatalError
+ if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread) {
// Switch to cooperative mode, since we'll be looking at managed objects
// and we don't want them moving on us.
@@ -3075,8 +3092,24 @@ static int GetThreadUICultureId(__out LocaleIDValue* pLocale)
Thread * pThread = GetThread();
- if (pThread != NULL) {
-
+ // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
+ // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
+ // getting localized with a non-default thread-specific culture.
+ // A canonical stack trace that gets here is a fatal error in the GC that comes through:
+ // coreclr.dll!GetThreadUICultureNames
+ // coreclr.dll!CCompRC::LoadLibraryHelper
+ // coreclr.dll!CCompRC::LoadLibrary
+ // coreclr.dll!CCompRC::GetLibrary
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResource
+ // coreclr.dll!EventReporter::EventReporter
+ // coreclr.dll!EEPolicy::LogFatalError
+ // coreclr.dll!EEPolicy::HandleFatalError
+ if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread)
+ {
// Switch to cooperative mode, since we'll be looking at managed objects
// and we don't want them moving on us.
GCX_COOP();
@@ -3134,7 +3167,24 @@ static int GetThreadUICultureId(__out LocaleIDValue* pLocale)
Thread * pThread = GetThread();
- if (pThread != NULL) {
+ // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
+ // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
+ // getting localized with a non-default thread-specific culture.
+ // A canonical stack trace that gets here is a fatal error in the GC that comes through:
+ // coreclr.dll!GetThreadUICultureNames
+ // coreclr.dll!CCompRC::LoadLibraryHelper
+ // coreclr.dll!CCompRC::LoadLibrary
+ // coreclr.dll!CCompRC::GetLibrary
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!CCompRC::LoadString
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResourceAndReturnHR
+ // coreclr.dll!SString::LoadResource
+ // coreclr.dll!EventReporter::EventReporter
+ // coreclr.dll!EEPolicy::LogFatalError
+ // coreclr.dll!EEPolicy::HandleFatalError
+ if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread)
+ {
// Switch to cooperative mode, since we'll be looking at managed objects
// and we don't want them moving on us.