internal static Task CollectDumpAsync(Process process, string outputFile, 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(); var dumpType = type == DumpType.Mini ? NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo : NativeMethods.MINIDUMP_TYPE.MiniDumpWithDataSegs | NativeMethods.MINIDUMP_TYPE.MiniDumpWithPrivateReadWriteMemory | NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData | NativeMethods.MINIDUMP_TYPE.MiniDumpWithUnloadedModules | NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo | NativeMethods.MINIDUMP_TYPE.MiniDumpWithTokenInformation; // Dump the process! if (!NativeMethods.MiniDumpWriteDump(process.Handle, (uint)process.Id, stream.SafeFileHandle, dumpType, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero)) { int err = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(err); } } })); }
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); } } } } })); }
/// <summary> /// Collects a mini dump (optionally with full memory) for the given process and writes it to the given file path /// </summary> public void CollectDump(Process process, string dumpFilePath, bool fIncludeFullHeap) { IntPtr hFile = IntPtr.Zero; try { hFile = NativeMethods.CreateFile( lpFileName: dumpFilePath, dwDesiredAccess: NativeMethods.EFileAccess.GenericWrite, dwShareMode: NativeMethods.EFileShare.None, lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: NativeMethods.ECreationDisposition.CreateAlways, dwFlagsAndAttributes: NativeMethods.EFileAttributes.Normal, hTemplateFile: IntPtr.Zero ); if (hFile == NativeMethods.INVALID_HANDLE_VALUE) { int hresult = Marshal.GetHRForLastWin32Error(); Exception hresultException = Marshal.GetExceptionForHR(hresult); throw hresultException; } // Ensure the dump file will contain all the info needed (full memory, handle, threads) NativeMethods.MINIDUMP_TYPE dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpNormal | NativeMethods.MINIDUMP_TYPE.MiniDumpWithHandleData | NativeMethods.MINIDUMP_TYPE.MiniDumpWithThreadInfo; if (fIncludeFullHeap) { dumpType |= NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemory | NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo; } NativeMethods.MINIDUMP_EXCEPTION_INFORMATION exceptionInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION(); bool result = NativeMethods.MiniDumpWriteDump( hProcess: process.Handle, ProcessId: process.Id, hFile: hFile, DumpType: dumpType, ExceptionParam: ref exceptionInfo, UserStreamParam: IntPtr.Zero, CallbackParam: IntPtr.Zero ); if (result == false) { int hresult = Marshal.GetHRForLastWin32Error(); Exception hresultException = Marshal.GetExceptionForHR(hresult); throw hresultException; } } finally { NativeMethods.CloseHandle(hFile); } }
internal static void CollectDump(Process process, string outputFile, DumpTypeOption type) { // Open the file for writing using (var stream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { NativeMethods.MINIDUMP_EXCEPTION_INFORMATION exceptionInfo = default(NativeMethods.MINIDUMP_EXCEPTION_INFORMATION); NativeMethods.MINIDUMP_TYPE dumpType = NativeMethods.MINIDUMP_TYPE.MiniDumpNormal; switch (type) { case DumpTypeOption.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 DumpTypeOption.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 DumpTypeOption.Mini: 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); } } } } }
internal static void Collect(Process process, string outputFile) { // Open the file for writing using (var stream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { // Dump the process! var exceptionInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION(); if (!NativeMethods.MiniDumpWriteDump(process.Handle, (uint)process.Id, stream.SafeFileHandle, NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemory, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero)) { var err = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(err); } } }
public Stream CreateMemoryDump(Process process) { string tempPath = Path.GetTempFileName(); // Open the file for writing var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); // Dump the process! var exceptionInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION(); if (!NativeMethods.MiniDumpWriteDump(process.Handle, (uint)process.Id, fileStream.SafeFileHandle, NativeMethods.MINIDUMP_TYPE.MiniDumpWithFullMemory, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero)) { var err = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(err); } fileStream.Seek(0, SeekOrigin.Begin); return(fileStream); }
public static string Create(Process process, NativeMethods._MINIDUMP_TYPE dumpType, string outputPath) { IntPtr hFile = IntPtr.Zero; if (IntPtr.Size == 4) { Console.WriteLine($"CreateMiniDump {dumpType} - Running as 32 bit, creating 32 bit dumps"); } else { Console.WriteLine($"CreateMiniDump {dumpType} - Running as 64 bit, creating 64 bit dumps"); } try { var dumpFileName = $@"{outputPath}\MiniDumpProcess-{dumpType.ToString()}.dmp"; if (File.Exists(dumpFileName)) { File.Delete(dumpFileName); } hFile = NativeMethods.CreateFile(dumpFileName, NativeMethods.EFileAccess.GenericWrite, NativeMethods.EFileShare.None, lpSecurityAttributes: IntPtr.Zero, dwCreationDisposition: NativeMethods.ECreationDisposition.CreateAlways, dwFlagsAndAttributes: NativeMethods.EFileAttributes.Normal, hTemplateFile: IntPtr.Zero ); if (hFile == NativeMethods.INVALID_HANDLE_VALUE) { var hr = Marshal.GetHRForLastWin32Error(); var ex = Marshal.GetExceptionForHR(hr); throw ex; } var exceptInfo = new NativeMethods.MINIDUMP_EXCEPTION_INFORMATION(); if (!process.Is32BitProcess() && IntPtr.Size == 4) { throw new InvalidOperationException("Can't create 32 bit dump of 64 bit process"); } var isDumpWrittenSuccessfully = NativeMethods.MiniDumpWriteDump(process.Handle, process.Id, hFile, dumpType, ref exceptInfo, UserStreamParam: IntPtr.Zero, CallbackParam: IntPtr.Zero); if (!isDumpWrittenSuccessfully) { var hr = Marshal.GetHRForLastWin32Error(); var ex = Marshal.GetExceptionForHR(hr); throw ex; } return(dumpFileName); } catch (Exception ex) { Console.WriteLine(ex); throw ex; } finally { NativeMethods.CloseHandle(hFile); } }