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;
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;
Console.WriteLine("createdump stderr:");
Console.WriteLine(error);
- if (crashReportPresent)
- {
- TryPrintStackTraceFromCrashReport(crashDumpPath + ".crashreport.json", outputWriter);
- }
+ TryPrintStackTraceFromCrashReport(crashDumpPath + ".crashreport.json", outputWriter);
}
else
{