/// <summary> /// Sets up for taking a snapshot by initializing the necessary handles for the helper process /// </summary> /// <remarks> /// This must be called from an Exception Filter inorder to gather the current exception information. /// </remarks> /// <returns>true on success and false on failure</returns> private unsafe bool InitializeHandlesForSnapshot() { // Grab the pointer to the exception _exceptionPointersPointer = Marshal.GetExceptionPointers(); NativeWin32Stubs.SECURITY_ATTRIBUTES secAttrib = new NativeWin32Stubs.SECURITY_ATTRIBUTES(); secAttrib.bInheritHandle = true; // Prepare id (ThreadId_DateTime) is sufficient to uniquely identify this snapshot request (used by helper process to name the dump file) _snapshotId = string.Format("{0}_{1}", Thread.CurrentThread.ManagedThreadId, unchecked ((ulong)DateTime.Now.ToBinary())); // pointer to the security attributes structure IntPtr pSecAttrib = IntPtr.Zero; // handle to this thread IntPtr hThread = IntPtr.Zero; try { // allocate some native to accommodate the SECURITY_ATTRIBUTES structure needed to create the event object and get its handle pSecAttrib = Marshal.AllocHGlobal(sizeof(NativeWin32Stubs.SECURITY_ATTRIBUTES)); if (pSecAttrib == IntPtr.Zero) { return(false); } // copy the managed structure into native Marshal.StructureToPtr(secAttrib, pSecAttrib, true); // Create event object in the OS (named eventHandleName) and get the handle to it _eventHandle = NativeWin32Stubs.CreateEvent(pSecAttrib, false, false, null); if (_eventHandle == IntPtr.Zero) { return(false); } // Get current thread and process' handle and duplicate them (when you open the handle on a System.Process you must dispose it) using (Process thisProc = Process.GetCurrentProcess()) { // Grab the handle to this thread hThread = NativeWin32Stubs.GetCurrentThread(); if (hThread == IntPtr.Zero) { return(false); } IntPtr hThisProc = thisProc.Handle; // duplicate the thread handle if (!NativeWin32Stubs.DuplicateHandle(hThisProc, hThread, hThisProc, out _threadHandleDupe, 0, true, (uint)NativeWin32Stubs.DESIRED_ACCESS.DUPLICATE_SAME_ACCESS) || _threadHandleDupe == IntPtr.Zero) { return(false); } // duplicate the process handle if (!NativeWin32Stubs.DuplicateHandle(hThisProc, hThisProc, hThisProc, out _processHandleDupe, 0, true, (uint)NativeWin32Stubs.DESIRED_ACCESS.DUPLICATE_SAME_ACCESS) || _processHandleDupe == IntPtr.Zero) { return(false); } } } finally // cleanup the temp handles and native memory we allocated { if (pSecAttrib != IntPtr.Zero) { Marshal.FreeHGlobal(pSecAttrib); } if (hThread != IntPtr.Zero) { NativeWin32Stubs.CloseHandle(hThread); } } return(true); }
/// <summary> /// Sets up for taking a snapshot by initializing the necessary handles for the helper process /// </summary> /// <remarks> /// This must be called from an Exception Filter inorder to gather the current exception information. /// </remarks> /// <returns>true on success and false on failure</returns> private unsafe bool InitializeHandlesForSnapshot() { // Grab the pointer the the exception _exceptionPointersPointer = Marshal.GetExceptionPointers(); NativeWin32Stubs.SECURITY_ATTRIBUTES secAttrib = new NativeWin32Stubs.SECURITY_ATTRIBUTES(); secAttrib.bInheritHandle = true; // Prepare id (ThreadId_DateTime) is sufficient to uniquely identify this snapshot request (used by helper process to name the dump file) _snapshotId = string.Format("{0}_{1}", Thread.CurrentThread.ManagedThreadId, unchecked((ulong)DateTime.Now.ToBinary())); // pointer to the security attributes structure IntPtr pSecAttrib = IntPtr.Zero; // handle to this thread IntPtr hThread = IntPtr.Zero; try { // allocate some native to accommodate the SECURITY_ATTRIBUTES structure needed to create the event object and get its handle pSecAttrib = Marshal.AllocHGlobal(sizeof(NativeWin32Stubs.SECURITY_ATTRIBUTES)); if (pSecAttrib == IntPtr.Zero) { return false; } // copy the managed structure into native Marshal.StructureToPtr(secAttrib, pSecAttrib, true); // Create event object in the OS (named eventHandleName) and get the handle to it _eventHandle = NativeWin32Stubs.CreateEvent(pSecAttrib, false, false, null); if (_eventHandle == IntPtr.Zero) { return false; } // Get current thread and process' handle and duplicate them (when you open the handle on a System.Process you must dispose it) using (Process thisProc = Process.GetCurrentProcess()) { // Grab the handle to this thread hThread = NativeWin32Stubs.GetCurrentThread(); if (hThread == IntPtr.Zero) { return false; } IntPtr hThisProc = thisProc.Handle; // duplicate the thread handle if (!NativeWin32Stubs.DuplicateHandle(hThisProc, hThread, hThisProc, out _threadHandleDupe, 0, true, (uint)NativeWin32Stubs.DESIRED_ACCESS.DUPLICATE_SAME_ACCESS) || _threadHandleDupe == IntPtr.Zero) { return false; } // duplicate the process handle if (!NativeWin32Stubs.DuplicateHandle(hThisProc, hThisProc, hThisProc, out _processHandleDupe, 0, true, (uint)NativeWin32Stubs.DESIRED_ACCESS.DUPLICATE_SAME_ACCESS) || _processHandleDupe == IntPtr.Zero) { return false; } } } finally // cleanup the temp handles and native memory we allocated { if (pSecAttrib != IntPtr.Zero) { Marshal.FreeHGlobal(pSecAttrib); } if (hThread != IntPtr.Zero) { NativeWin32Stubs.CloseHandle(hThread); } } return true; }