Create dump in utility thread after m_LastThrownObjectHandle has been set (#40915)
authorMike McLaughlin <mikem@microsoft.com>
Mon, 17 Aug 2020 18:59:06 +0000 (11:59 -0700)
committerGitHub <noreply@github.com>
Mon, 17 Aug 2020 18:59:06 +0000 (11:59 -0700)
The previous Windows stack overflow createdump trigger fix generated the dump before the m_LastThrownObjectHandle in the thread was set. This breaks SOS's !pe command.

src/coreclr/src/utilcode/debug.cpp
src/coreclr/src/utilcode/hostimpl.cpp
src/coreclr/src/vm/eepolicy.cpp
src/coreclr/src/vm/excep.cpp
src/coreclr/src/vm/excep.h

index d6c2c4a..b4f44dc 100644 (file)
@@ -23,7 +23,7 @@
 extern "C" _CRTIMP int __cdecl _flushall(void);
 
 #ifdef HOST_WINDOWS
-void CreateCrashDumpIfEnabled();
+void CreateCrashDumpIfEnabled(bool stackoverflow = false);
 #endif
 
 // Global state counter to implement SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE.
index 31d38df..c1e4b53 100644 (file)
@@ -76,7 +76,7 @@ void GetLastThrownObjectExceptionFromThread(Exception** ppException)
 }
 
 #ifdef HOST_WINDOWS
-void CreateCrashDumpIfEnabled()
+void CreateCrashDumpIfEnabled(bool stackoverflow)
 {
 }
 #endif
index 7352fb4..04eea40 100644 (file)
@@ -585,9 +585,7 @@ void DisplayStackOverflowException()
 DWORD LogStackOverflowStackTraceThread(void* arg)
 {
     LogCallstackForLogWorker((Thread*)arg);
-#ifdef HOST_WINDOWS
-    CreateCrashDumpIfEnabled();
-#endif
+
     return 0;
 }
 
index 97659d3..a2f01b5 100644 (file)
@@ -3835,7 +3835,7 @@ LONG WatsonLastChance(                  // EXCEPTION_CONTINUE_SEARCH, _CONTINUE_
 
                 STRESS_LOG0(LF_CORDB, LL_INFO10, "D::RFFE: About to call RaiseFailFastException\n");
 #ifdef HOST_WINDOWS
-                CreateCrashDumpIfEnabled();
+                CreateCrashDumpIfEnabled(fSOException);
 #endif
                 RaiseFailFastException(pExceptionInfo == NULL ? NULL : pExceptionInfo->ExceptionRecord,
                                        pExceptionInfo == NULL ? NULL : pExceptionInfo->ContextRecord,
@@ -4085,10 +4085,10 @@ BuildCreateDumpCommandLine(
     }
 }
 
-static bool
+static DWORD 
 LaunchCreateDump(LPCWSTR lpCommandLine)
 {
-    bool fSuccess = false;
+    DWORD fSuccess = false;
 
     EX_TRY
     {
@@ -4117,13 +4117,26 @@ LaunchCreateDump(LPCWSTR lpCommandLine)
 }
 
 void
-CreateCrashDumpIfEnabled()
+CreateCrashDumpIfEnabled(bool stackoverflow)
 {
     // If enabled, launch the create minidump utility and wait until it completes. Only launch createdump once for this process.
     LPCWSTR createDumpCommandLine = InterlockedExchangeT<LPCWSTR>(&g_createDumpCommandLine, nullptr);
     if (createDumpCommandLine != nullptr)
     {
-        LaunchCreateDump(createDumpCommandLine);
+        if (stackoverflow)
+        {
+            HandleHolder createDumpThreadHandle = Thread::CreateUtilityThread(Thread::StackSize_Small, (LPTHREAD_START_ROUTINE)LaunchCreateDump, (void*)createDumpCommandLine, W(".NET Stack overflow create dump"));
+            if (createDumpThreadHandle != INVALID_HANDLE_VALUE)
+            {
+                // Wait for the dump to be generated
+                DWORD res = WaitForSingleObject(createDumpThreadHandle, INFINITE);
+                _ASSERTE(res == WAIT_OBJECT_0);
+            }
+        }
+        else
+        {
+            LaunchCreateDump(createDumpCommandLine);
+        }
     }
 }
 
@@ -4172,7 +4185,7 @@ InitializeCrashDump()
 void CrashDumpAndTerminateProcess(UINT exitCode)
 {
 #ifdef HOST_WINDOWS
-    CreateCrashDumpIfEnabled();
+    CreateCrashDumpIfEnabled(exitCode == COR_E_STACKOVERFLOW);
 #endif
     TerminateProcess(GetCurrentProcess(), exitCode);
 }
index 28bcaa3..365c2d1 100644 (file)
@@ -197,7 +197,7 @@ enum UnhandledExceptionLocation
 #ifdef HOST_WINDOWS
 void InitializeCrashDump();
 bool GenerateCrashDump(LPCWSTR dumpName, int dumpType, bool diag);
-void CreateCrashDumpIfEnabled();
+void CreateCrashDumpIfEnabled(bool stackoverflow = false);
 #endif
 
 // Generates crash dumps if enabled for both Windows and Linux