diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp
index 1fd898684cf1c..f025aed4a5f5a 100644
--- a/src/coreclr/vm/ceemain.cpp
+++ b/src/coreclr/vm/ceemain.cpp
@@ -1727,6 +1727,11 @@ struct TlsDestructionMonitor
m_activated = true;
}
+ void Deactivate()
+ {
+ m_activated = false;
+ }
+
~TlsDestructionMonitor()
{
if (m_activated)
@@ -1768,6 +1773,11 @@ void EnsureTlsDestructionMonitor()
tls_destructionMonitor.Activate();
}
+void DeactivateTlsDestructionMonitor()
+{
+ tls_destructionMonitor.Deactivate();
+}
+
#ifdef DEBUGGING_SUPPORTED
//
// InitializeDebugger initialized the Runtime-side COM+ Debugging Services
diff --git a/src/coreclr/vm/ceemain.h b/src/coreclr/vm/ceemain.h
index 1404a5a04237f..48ed60c3a7a26 100644
--- a/src/coreclr/vm/ceemain.h
+++ b/src/coreclr/vm/ceemain.h
@@ -46,6 +46,7 @@ void ForceEEShutdown(ShutdownCompleteAction sca = SCA_ExitProcessWhenShutdownCom
void ThreadDetaching();
void EnsureTlsDestructionMonitor();
+void DeactivateTlsDestructionMonitor();
void SetLatchedExitCode (INT32 code);
INT32 GetLatchedExitCode (void);
diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp
index af27338544e86..7dc22a2eedef4 100644
--- a/src/coreclr/vm/eepolicy.cpp
+++ b/src/coreclr/vm/eepolicy.cpp
@@ -78,6 +78,13 @@ void SafeExitProcess(UINT exitCode, ShutdownCompleteAction sca = SCA_ExitProcess
// disabled because if we fault in this code path we will trigger our Watson code
CONTRACT_VIOLATION(ThrowsViolation);
+ // The TlsDestructionMonitor for this thread would likely be destructed at some point after ExitProcess is called. On
+ // Windows, this happens after all other threads in the process are torn down, and may occur while a GC is in progress.
+ // The thread cleanup code in TlsDestructionMonitor may try to enter cooperative GC mode to fix the frame pointer and
+ // wait for the pending GC to complete, leading to a hang. Since the process is being exited, deactivate the
+ // TlsDestructionMonitor for this thread before calling ExitProcess.
+ DeactivateTlsDestructionMonitor();
+
ExitProcess(exitCode);
}
}
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index e142ff1292411..7d95fa9bc4a75 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -30,6 +30,9 @@
This test is to verify we are running mono, and therefore only makes sense on mono.
+
+ https://github.com/dotnet/runtime/issues/83658
+
https://github.com/dotnet/runtime/issues/5933
@@ -251,9 +254,6 @@
-
- https://github.com/dotnet/runtime/issues/84006
-