public void Dump(int pid, DumpType dumpType, string fileName, string dumpComment = null) { _pid = pid; _dumpType = dumpType; dumpComment = dumpComment ?? ("DumpWriter: " + _dumpType.ToString()); IntPtr hProcess = DumpNativeMethods.OpenProcess( ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryRead | ProcessAccessFlags.DuplicateHandle, false, (uint)_pid ); if (hProcess == IntPtr.Zero) { throw new ArgumentException(String.Format("Unable to open process {0}, error {x:8}", _pid, Marshal.GetLastWin32Error())); } FileStream dumpFileStream = new FileStream(fileName, FileMode.Create); var exceptionParam = new MINIDUMP_EXCEPTION_INFORMATION(); var userStreamParam = PrepareUserStream(dumpComment); var callbackParam = new MINIDUMP_CALLBACK_INFORMATION(); if (_dumpType == DumpType.FullMemoryExcludingSafeRegions || _dumpType == DumpType.MinimalWithFullCLRHeap) { callbackParam.CallbackRoutine = CallbackRoutine; } MINIDUMP_TYPE nativeDumpType = (_dumpType == DumpType.FullMemory || _dumpType == DumpType.FullMemoryExcludingSafeRegions) ? MINIDUMP_TYPE.MiniDumpWithFullMemory | MINIDUMP_TYPE.MiniDumpWithHandleData | MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo : MINIDUMP_TYPE.MiniDumpWithHandleData | MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo; bool success = DumpNativeMethods.MiniDumpWriteDump( hProcess, (uint)_pid, dumpFileStream.SafeFileHandle.DangerousGetHandle(), nativeDumpType, ref exceptionParam, ref userStreamParam, ref callbackParam ); if (!success) { throw new ApplicationException(String.Format("Error writing dump, error {0:x8}", Marshal.GetLastWin32Error())); } userStreamParam.Delete(); DumpNativeMethods.CloseHandle(hProcess); dumpFileStream.Close(); }
public void Dump(int pid, DumpType dumpType, IntPtr exceptionParam, string fileName, bool writeAsync = false, string dumpComment = null) { _pid = pid; _dumpType = dumpType; _spillSegmentsAsynchronously = writeAsync; dumpComment = dumpComment ?? ("DumpWriter: " + _dumpType.ToString()); IntPtr hProcess = DumpNativeMethods.OpenProcess( ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryRead | ProcessAccessFlags.DuplicateHandle, false, (uint)_pid ); if (hProcess == IntPtr.Zero) { throw new ArgumentException(String.Format("Unable to open process {0}, error {1:x8}", _pid, Marshal.GetLastWin32Error())); } _dumpFileStream = new FileStream(fileName, FileMode.Create); var userStreamParam = PrepareUserStream(dumpComment); var callbackParam = new MINIDUMP_CALLBACK_INFORMATION(); _needMemoryCallbacks = ( _dumpType == DumpType.FullMemoryExcludingSafeRegions || _dumpType == DumpType.MinimalWithFullCLRHeap ); if (_needMemoryCallbacks || _spillSegmentsAsynchronously) { callbackParam.CallbackRoutine = CallbackRoutine; } MINIDUMP_TYPE nativeDumpType = (_dumpType == DumpType.FullMemory || _dumpType == DumpType.FullMemoryExcludingSafeRegions) ? MINIDUMP_TYPE.MiniDumpWithFullMemory | MINIDUMP_TYPE.MiniDumpWithHandleData | MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo : MINIDUMP_TYPE.MiniDumpWithHandleData | MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo; Stopwatch sw = Stopwatch.StartNew(); bool success = DumpNativeMethods.MiniDumpWriteDump( hProcess, (uint)_pid, _dumpFileStream.SafeFileHandle.DangerousGetHandle(), nativeDumpType, exceptionParam, ref userStreamParam, ref callbackParam); if (!success) { throw new ApplicationException(string.Format("Error writing dump, error: {0}", Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error()))); } _logger.WriteLine("Process was suspended for {0:N2}ms", sw.Elapsed.TotalMilliseconds); if (_spillSegmentsAsynchronously) { // We are asynchronously spilling dump segments to disk, need to wait // for this process to complete before returning to the caller. _segmentSpillingTask.Wait(); _logger.WriteLine( "Total dump writing time including async flush was {0:N2}ms", sw.Elapsed.TotalMilliseconds); } userStreamParam.Delete(); DumpNativeMethods.CloseHandle(hProcess); _dumpFileStream.Close(); }