diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index 508693767fa8..11c781a132c9 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -1311,6 +1311,10 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) if (fIsDllUnloading) { + // The process is detaching, so set the global state. + // This is used to get around FreeLibrary problems. + g_fProcessDetach = true; + ETW::EnumerationLog::ProcessShutdown(); } @@ -1327,11 +1331,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) Thread * pThisThread = GetThread(); #endif - // If the process is detaching then set the global state. - // This is used to get around FreeLibrary problems. - if(fIsDllUnloading) - g_fProcessDetach = true; - if (IsDbgHelperSpecialThread()) { // Our debugger helper thread does not allow Thread object to be set up. diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index b76a018daf21..7ea3519e31e5 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -1197,7 +1197,13 @@ PrepareCodeConfig::JitOptimizationTier PrepareCodeConfig::GetJitOptimizationTier _ASSERTE(methodDesc != nullptr); _ASSERTE(config == nullptr || methodDesc == config->GetMethodDesc()); - if (config != nullptr) + // The code inside this block may take one or more locks. If process detach has already occurred, then other threads would + // have already been abruptly terminated, which may have left locks orphaned, so it would not be feasible to attempt taking + // a lock on process detach. This function is called from ETW-related code on shutdown where unfortunately it processes and + // sends rundown events upon process detach. If process detach has already occurred, then resort to best-effort behavior + // that may return inaccurate information. This is a temporary and targeted fix for a clear problem, and should not be used + // long-term. + if (config != nullptr && !g_fProcessDetach) { if (config->JitSwitchedToMinOpt()) {