internal static Task CollectDumpAsync(Process process, string outputFile, NETCore.Client.DumpType type) { // We can't do this "asynchronously" so just Task.Run it. It shouldn't be "long-running" so this is fairly safe. return(Task.Run(() => { // Open the file for writing using (var stream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { var exceptionInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION(); NativeMethods.MINIDUMP_TYPE dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpNormal; switch (type) { case NETCore.Client.DumpType.Full: dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemory | NativeMethods.MINIDUMP_TYPE.MiniDumpWithDataSegs | NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData | NativeMethods.MINIDUMP_TYPE.MiniDumpWithUnloadedModules | NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithTokenInformation; break; case NETCore.Client.DumpType.WithHeap: dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpWithPrivateReadWriteMemory | NativeMethods.MINIDUMP_TYPE.MiniDumpWithDataSegs | NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData | NativeMethods.MINIDUMP_TYPE.MiniDumpWithUnloadedModules | NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithTokenInformation; break; case NETCore.Client.DumpType.Normal: dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo; break; } // Retry the write dump on ERROR_PARTIAL_COPY for (int i = 0; i < 5; i++) { // Dump the process! if (NativeMethods.MiniDumpWriteDump(process.Handle, (uint)process.Id, stream.SafeFileHandle, dumpType, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero)) { break; } else { int err = Marshal.GetHRForLastWin32Error(); if (err != NativeMethods.ERROR_PARTIAL_COPY) { Marshal.ThrowExceptionForHR(err); } } } } })); }
public async Task <Stream> GetDump(IProcessInfo pi, DumpType mode, CancellationToken token) { string dumpFilePath = Path.Combine(Path.GetTempPath(), FormattableString.Invariant($"{Guid.NewGuid()}_{pi.ProcessId}")); NETCore.Client.DumpType dumpType = MapDumpType(mode); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Get the process Process process = Process.GetProcessById(pi.ProcessId); await Dumper.CollectDumpAsync(process, dumpFilePath, dumpType); } else { await Task.Run(() => { pi.Client.WriteDump(dumpType, dumpFilePath); }); } return(new AutoDeleteFileStream(dumpFilePath)); }
public async Task <Stream> GetDump(int pid, DumpType mode) { string dumpFilePath = FormattableString.Invariant($@"{Path.GetTempPath()}{Path.DirectorySeparatorChar}{Guid.NewGuid()}_{pid}"); NETCore.Client.DumpType dumpType = MapDumpType(mode); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Get the process Process process = Process.GetProcessById(pid); await Dumper.CollectDumpAsync(process, dumpFilePath, dumpType); } else { await Task.Run(() => { var client = new DiagnosticsClient(pid); client.WriteDump(dumpType, dumpFilePath); }); } return(new AutoDeleteFileStream(dumpFilePath)); }