Use MiniDumpWriteDump to create dumps on Windows (#81509)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Tue, 7 Feb 2023 21:19:13 +0000 (13:19 -0800)
committerGitHub <noreply@github.com>
Tue, 7 Feb 2023 21:19:13 +0000 (13:19 -0800)
src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs

index 39078a5..81c5f48 100644 (file)
@@ -20,6 +20,39 @@ using Microsoft.Win32.SafeHandles;
 
 namespace CoreclrTestLib
 {
+    static class DbgHelp
+    {
+        public enum MiniDumpType : int
+        {
+            MiniDumpNormal                          = 0x00000000,
+            MiniDumpWithDataSegs                    = 0x00000001,
+            MiniDumpWithFullMemory                  = 0x00000002,
+            MiniDumpWithHandleData                  = 0x00000004,
+            MiniDumpFilterMemory                    = 0x00000008,
+            MiniDumpScanMemory                      = 0x00000010,
+            MiniDumpWithUnloadedModules             = 0x00000020,
+            MiniDumpWithIndirectlyReferencedMemory  = 0x00000040,
+            MiniDumpFilterModulePaths               = 0x00000080,
+            MiniDumpWithProcessThreadData           = 0x00000100,
+            MiniDumpWithPrivateReadWriteMemory      = 0x00000200,
+            MiniDumpWithoutOptionalData             = 0x00000400,
+            MiniDumpWithFullMemoryInfo              = 0x00000800,
+            MiniDumpWithThreadInfo                  = 0x00001000,
+            MiniDumpWithCodeSegs                    = 0x00002000,
+            MiniDumpWithoutAuxiliaryState           = 0x00004000,
+            MiniDumpWithFullAuxiliaryState          = 0x00008000,
+            MiniDumpWithPrivateWriteCopyMemory      = 0x00010000,
+            MiniDumpIgnoreInaccessibleMemory        = 0x00020000,
+            MiniDumpWithTokenInformation            = 0x00040000,
+            MiniDumpWithModuleHeaders               = 0x00080000,
+            MiniDumpFilterTriage                    = 0x00100000,
+            MiniDumpValidTypeFlags                  = 0x001fffff
+        }
+
+        [DllImport("DbgHelp.dll", SetLastError = true)]
+        public static extern bool MiniDumpWriteDump(IntPtr handle, int processId, SafeFileHandle file, MiniDumpType dumpType, IntPtr exceptionParam, IntPtr userStreamParam, IntPtr callbackParam);
+    }
+
     static class Kernel32
     {
         public const int MAX_PATH = 260;
@@ -209,23 +242,34 @@ namespace CoreclrTestLib
 
         static bool CollectCrashDump(Process process, string crashDumpPath, StreamWriter outputWriter)
         {
-            string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT");
-            string createdumpPath = Path.Combine(coreRoot, "createdump");
-            string arguments = $"--name \"{crashDumpPath}\" {process.Id} --withheap";
-            Process createdump = new Process();
-            bool crashReportPresent = false;
-
             if (OperatingSystem.IsWindows())
             {
-                createdump.StartInfo.FileName = createdumpPath + ".exe";
-                createdump.StartInfo.Arguments = arguments;
+                return CollectCrashDumpWithMiniDumpWriteDump(process, crashDumpPath, outputWriter);
             }
-            else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
+            else
             {
-                createdump.StartInfo.FileName = "sudo";
-                createdump.StartInfo.Arguments = $"{createdumpPath} --crashreport {arguments}";
-                crashReportPresent = true;
+                return CollectCrashDumpWithCreateDump(process, crashDumpPath, outputWriter);
             }
+        }
+
+        static bool CollectCrashDumpWithMiniDumpWriteDump(Process process, string crashDumpPath, StreamWriter outputWriter)
+        {
+            using (var crashDump = File.OpenWrite(crashDumpPath))
+            {
+                var flags = DbgHelp.MiniDumpType.MiniDumpWithFullMemory | DbgHelp.MiniDumpType.MiniDumpIgnoreInaccessibleMemory;
+                return DbgHelp.MiniDumpWriteDump(process.Handle, process.Id, crashDump.SafeFileHandle, flags, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+            }
+        }
+
+        static bool CollectCrashDumpWithCreateDump(Process process, string crashDumpPath, StreamWriter outputWriter)
+        {
+            string coreRoot = Environment.GetEnvironmentVariable("CORE_ROOT");
+            string createdumpPath = Path.Combine(coreRoot, "createdump");
+            string arguments = $"--crashreport --name \"{crashDumpPath}\" {process.Id} --withheap";
+            Process createdump = new Process();
+
+            createdump.StartInfo.FileName = "sudo";
+            createdump.StartInfo.Arguments = $"{createdumpPath} {arguments}";
 
             createdump.StartInfo.UseShellExecute = false;
             createdump.StartInfo.RedirectStandardOutput = true;
@@ -249,10 +293,7 @@ namespace CoreclrTestLib
                 Console.WriteLine("createdump stderr:");
                 Console.WriteLine(error);
 
-                if (crashReportPresent)
-                {
-                    TryPrintStackTraceFromCrashReport(crashDumpPath + ".crashreport.json", outputWriter);
-                }
+                TryPrintStackTraceFromCrashReport(crashDumpPath + ".crashreport.json", outputWriter);
             }
             else
             {