diff options
author | Sung Yoon Whang <suwhang@microsoft.com> | 2018-04-20 23:05:00 -0700 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-04-20 23:05:00 -0700 |
commit | 1c8c59387cb5989b5494f346c8127feb9dff27bc (patch) | |
tree | d73a23d4af1044c445f21cdbb06321071e810e10 /src/vm/ceemain.cpp | |
parent | 69e3ed349763a427f5b47513ec48484dbbed7397 (diff) | |
download | coreclr-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.cpp | 58 |
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. |