Results 1 to 3 of 3

Thread: Memory Dumps

  1. #1
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default Memory Dumps

    Hey everyone, I appear to be having some trouble with this, so I was wondering if anyone was familiar with any methods of programmatically taking process dumps in .NET. I've looked into minidumps and even with all parameters included, it's not dumping enough information. ProcDump is a wonderful program, but it does not fit my needs as it runs within a separate window and I can't instantiate a separate program with the necessary rights (however, if I had access to some of ProcDump's code, I think that could solve my problem).

    Does anyone have any other ideas?

    Edit: (Just spoke with Cru1z1n) To clarify, performance analysis will be running on a dedicated thread to watch memory/threads/cpu/etc of my process and at a given threshold, I will want to programmatically take a full dump of the process.

  2. #2
    Join Date
    May 2007
    Location
    England/Liverpool
    Posts
    1,004
    Mentioned
    9 Post(s)
    Quoted
    106 Post(s)

    Default

    you could try process explorer i think its the same as procdump never used that one tbh

  3. #3
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default

    Oh yeah. Spam bot reminds me I solved this... C# Code for the memory dumps in case anyone is interested:
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    
    namespace Custom.Utilities
    {
    	/// <summary>
    	/// The MiniDump class used to Write out memory dumps of the current process.
    	/// For the souce of roughly 75% of this code and related MSDN description: http://blogs.msdn.com/b/dondu/archive/2010/10/24/writing-minidumps-in-c.aspx
    	/// For extended information on the background design of this class: http://www.debuginfo.com/articles/effminidumps.html
    	/// </summary>
    	public sealed class MiniDump
    	{
    		/// <summary>
    		/// Whether a dump is currently being taken
    		/// </summary>
    		private static bool currentlyDumping = false;
    
    		// Missing XML comment for publicly visible type or member 'Type_or_Member' - exists because a definition is desired on each member of the Typ enum below and suppression is not working.
    		#pragma warning disable 1591
    
    		/// <summary>
    		/// The listing of flags used for different memory writes.
    		/// </summary>
    		[Flags]
    		public enum Typ : uint
    		{
    			// From dbghelp.h:
    			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,
    			MiniDumpValidTypeFlags = 0x0003ffff,
    		};
    
    		// Missing XML comment for publicly visible type or member 'Type_or_Member' - exists because a definition is desired on each member of the Typ enum above.
    		#pragma warning restore 1591
    
    		/// <summary>
    		/// The structure representing the minidump exception
    		/// </summary>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable", Justification="Microsoft created method AND suppression"), StructLayout(LayoutKind.Sequential, Pack = 4)]  // Pack=4 is important! So it works also for x64!
    		struct MiniDumpExceptionInformation
    		{
    			public uint ThreadId;
    			[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
    			public IntPtr ExceptionPointers;
    			[MarshalAs(UnmanagedType.Bool)]
    			public bool ClientPointers;
    		}
    
    		/// <summary>
    		/// Write out the dump with exception.
    		/// </summary>
    		/// <param name="hProcess"></param>
    		/// <param name="processId"></param>
    		/// <param name="hFile"></param>
    		/// <param name="dumpType"></param>
    		/// <param name="expParam"></param>
    		/// <param name="userStreamParam"></param>
    		/// <param name="callbackParam"></param>
    		/// <returns></returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "Microsoft created method AND suppression"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1414:MarkBooleanPInvokeArgumentsWithMarshalAs"), DllImport("dbghelp.dll",
    		  EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
    		static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, IntPtr hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
    
    		/// <summary>
    		/// Write out the dump without exception.
    		/// </summary>
    		/// <param name="hProcess"></param>
    		/// <param name="processId"></param>
    		/// <param name="hFile"></param>
    		/// <param name="dumpType"></param>
    		/// <param name="expParam"></param>
    		/// <param name="userStreamParam"></param>
    		/// <param name="callbackParam"></param>
    		/// <returns></returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "Microsoft created method AND suppression"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1414:MarkBooleanPInvokeArgumentsWithMarshalAs"), DllImport("dbghelp.dll",
    		  EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
    		static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, IntPtr hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);
    
    		/// <summary>
    		/// Retrieves the current thread's ID
    		/// </summary>
    		/// <returns></returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "Microsoft created method AND suppression"), DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
    		static extern uint GetCurrentThreadId();
    
    		/// <summary>
    		/// Retrieves the current Process
    		/// </summary>
    		/// <returns></returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "Microsoft created method AND suppression"), DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
    		static extern IntPtr GetCurrentProcess();
    
    		/// <summary>
    		/// Retrieves the current process's ID
    		/// </summary>
    		/// <returns></returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "Microsoft created method AND suppression"), DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
    		static extern uint GetCurrentProcessId();
    
    		/// <summary>
    		/// Write a dump to given location with all flags set, assuming no exception was thrown, and to a default time based log location.
    		/// </summary>
    		/// <returns>The successful completion of the dump.  Will fail if trying to create a dump while a dump is running.</returns>
    		public static bool Write()
    		{
    			return Write("D:\\data\\Dump-" + DateTime.Now.ToString("yyyyMMdd", CultureInfo.InvariantCulture) + ".dmp");
    		}
    
    		/// <summary>
    		/// Write a dump to given location with all flags set, assuming no exception was thrown.
    		/// </summary>
    		/// <param name="fileName">Where to log to</param>
    		/// <returns>The successful completion of the dump.  Will fail if trying to create a dump while a dump is running.</returns>
    		public static bool Write(string fileName)
    		{
    			return Write(fileName, (uint)(Typ.MiniDumpWithFullMemory | Typ.MiniDumpWithFullMemoryInfo | Typ.MiniDumpWithHandleData | Typ.MiniDumpWithThreadInfo | Typ.MiniDumpWithUnloadedModules), false);
    		}
    
    		/// <summary>
    		/// Write a dump to given location using the given dump type.
    		/// </summary>
    		/// <param name="fileName">Where to log to</param>
    		/// <param name="dumpTyp">The type of dump to take</param>
    		/// <param name="exceptionRaised">Whether an unhandled exception was raised to reach here</param>
    		/// <returns>The successful completion of the dump.  Will fail if trying to create a dump while a dump is running.</returns>
    		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Justification="Calling internal sealed code in this situation is recommended by Microsoft.")]
    		public static bool Write(string fileName, uint dumpTyp, bool exceptionRaised)
    		{
    			if (currentlyDumping)
    			{
    				return false;
    			}
    			currentlyDumping = true;
    			using (var fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
    			{
    				IntPtr proc = GetCurrentProcess();
    				uint procId = GetCurrentProcessId();
    				IntPtr handle = fs.SafeFileHandle.DangerousGetHandle();
    				bool success = false;
    				if (exceptionRaised)
    				{
    					MiniDumpExceptionInformation exp;
    					exp.ThreadId = GetCurrentThreadId();
    					exp.ClientPointers = false;
    					exp.ExceptionPointers = System.Runtime.InteropServices.Marshal.GetExceptionPointers();
    					success = MiniDumpWriteDump(proc, procId, handle, (uint)dumpTyp, ref exp, IntPtr.Zero, IntPtr.Zero);
    				}
    				else
    				{
    					success = MiniDumpWriteDump(proc, procId, handle, (uint)dumpTyp, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
    				}
    				currentlyDumping = false;
    				return success;
    			}
    		}
    	}
    }
    I also have some code to analyze current performance counters as well if anyone cares to see.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •