diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index 1c5d4f885246..8a5bb4f4e697 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -1323,6 +1323,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(); } @@ -1339,11 +1343,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..a8d3e4247ad1 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -1197,6 +1197,17 @@ PrepareCodeConfig::JitOptimizationTier PrepareCodeConfig::GetJitOptimizationTier _ASSERTE(methodDesc != nullptr); _ASSERTE(config == nullptr || methodDesc == config->GetMethodDesc()); + // The code below 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 (g_fProcessDetach) + { + return JitOptimizationTier::Unknown; + } + if (config != nullptr) { if (config->JitSwitchedToMinOpt())