Exemple #1
0
        internal static Result DumpProcess(FileStream dumpFile, IntPtr processHandle, int pid)
        {
            IntPtr   callbackParam  = default;
            Result   result         = default;
            GCHandle callbackHandle = default;

            try
            {
                var callbackDelegate = new MiniDumpCallback(MiniDumpCallbackMethod);
                callbackHandle = GCHandle.Alloc(callbackDelegate);
                callbackParam  = Marshal.AllocHGlobal(IntPtr.Size * 2);

                unsafe
                {
                    var ptr = (MINIDUMP_CALLBACK_INFORMATION *)callbackParam;
                    ptr->CallbackRoutine = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
                    ptr->CallbackParam   = IntPtr.Zero;
                }

#pragma warning disable S3869 // "SafeHandle.DangerousGetHandle" should not be called
                var fileHandle = dumpFile.SafeFileHandle.DangerousGetHandle();
#pragma warning restore S3869 // "SafeHandle.DangerousGetHandle" should not be called

                result.ReturnValue = MiniDumpWriteDump(processHandle, pid, fileHandle, GetMiniDumpType(), IntPtr.Zero, IntPtr.Zero, callbackParam);
                result.ErrorCode   = Marshal.GetHRForLastWin32Error();
            }
            catch (Exception e)
            {
                result.ErrorCode   = Marshal.GetHRForLastWin32Error();
                result.ReturnValue = 0;
                result.Exception   = e;
            }
            finally
            {
                if (callbackParam != default)
                {
                    Marshal.FreeHGlobal(callbackParam);
                }

                if (callbackHandle.IsAllocated)
                {
                    callbackHandle.Free();
                }
            }

            return(result);
        }
Exemple #2
0
        internal static Result DumpProcess(FileStream dumpFile, IntPtr processHandle, int pid)
        {
            IntPtr callbackParam = default(IntPtr);
            Result result        = default(Result);

            try
            {
                var callbackDelegate = new MiniDumpCallback(MiniDumpCallbackMethod);
                callbackParam = Marshal.AllocHGlobal(IntPtr.Size * 2);

                unsafe
                {
                    var ptr = (MINIDUMP_CALLBACK_INFORMATION *)callbackParam;
                    ptr->CallbackRoutine = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
                    ptr->CallbackParam   = IntPtr.Zero;
                }

                var fileHandle = dumpFile.SafeFileHandle.DangerousGetHandle();
                GC.KeepAlive(callbackDelegate);

                result.ReturnValue = MiniDumpWriteDump(processHandle, pid, fileHandle, GetMiniDumpType(), IntPtr.Zero, IntPtr.Zero, callbackParam);
                result.ErrorCode   = Marshal.GetHRForLastWin32Error();
            }
            catch (Exception e)
            {
                result.ErrorCode   = Marshal.GetHRForLastWin32Error();
                result.ReturnValue = 0;
                result.Exception   = e;
            }
            finally
            {
                if (callbackParam != default(IntPtr))
                {
                    Marshal.FreeHGlobal(callbackParam);
                }
            }

            return(result);
        }
Exemple #3
0
        public static int Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: CopyOnWriteDump <PID> <FileName.dmp>");
                return(-1);
            }

            var    pid      = int.Parse(args[0]);
            var    fileName = args[1];
            HANDLE handle;

            try
            {
                var p = Process.GetProcessById(pid);
                handle = p.Handle;
            }
            catch (ArgumentException)
            {
                Console.WriteLine($"Process identified by {pid} does not exist");
                return(-2);
            }

            var flags = PSS_CAPTURE_FLAGS.PSS_CAPTURE_VA_CLONE |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLES |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_NAME_INFORMATION |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_BASIC_INFORMATION |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_HANDLE_TRACE |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_THREADS |
                        PSS_CAPTURE_FLAGS.PSS_CAPTURE_THREAD_CONTEXT |
                        PSS_CAPTURE_FLAGS.PSS_CREATE_MEASURE_PERFORMANCE;

            HPSS      snapshotHandle;
            Stopwatch sw = new Stopwatch();

            sw.Start();
            DWORD hr = PssCaptureSnapshot(handle, flags, IntPtr.Size == 8 ? 0x0010001F : 0x0001003F, out snapshotHandle);

            sw.Stop();

            if (hr != 0)
            {
                Console.WriteLine($"PssCaptureSnapshot failed. ({hr})");
                return(hr);
            }

            Console.WriteLine($"Snapshot Creation Time: {sw.ElapsedMilliseconds}ms");

            sw.Reset();
            sw.Start();

            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                var callbackDelegate = new MiniDumpCallback(MiniDumpCallbackMethod);
                var callbackParam    = Marshal.AllocHGlobal(IntPtr.Size * 2);

                unsafe
                {
                    var ptr = (MINIDUMP_CALLBACK_INFORMATION *)callbackParam;
                    ptr->CallbackRoutine = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
                    ptr->CallbackParam   = IntPtr.Zero;
                }

                var minidumpFlags = MINIDUMP_TYPE.MiniDumpWithDataSegs |
                                    MINIDUMP_TYPE.MiniDumpWithTokenInformation |
                                    MINIDUMP_TYPE.MiniDumpWithPrivateWriteCopyMemory |
                                    MINIDUMP_TYPE.MiniDumpWithPrivateReadWriteMemory |
                                    MINIDUMP_TYPE.MiniDumpWithUnloadedModules |
                                    MINIDUMP_TYPE.MiniDumpWithFullMemory |
                                    MINIDUMP_TYPE.MiniDumpWithHandleData |
                                    MINIDUMP_TYPE.MiniDumpWithThreadInfo |
                                    MINIDUMP_TYPE.MiniDumpWithFullMemoryInfo |
                                    MINIDUMP_TYPE.MiniDumpWithProcessThreadData |
                                    MINIDUMP_TYPE.MiniDumpWithModuleHeaders;

                hr = MiniDumpWriteDump(snapshotHandle, pid, fs.SafeFileHandle.DangerousGetHandle(), minidumpFlags, IntPtr.Zero, IntPtr.Zero, callbackParam);

                IntPtr vaCloneHandle;
                PssQuerySnapshot(snapshotHandle, PSS_QUERY_INFORMATION_CLASS.PSS_QUERY_VA_CLONE_INFORMATION, out vaCloneHandle, IntPtr.Size);

                var cloneProcessId = GetProcessId(vaCloneHandle);

                PssFreeSnapshot(Process.GetCurrentProcess().Handle, snapshotHandle);
                CloseHandle(vaCloneHandle);

                try
                {
                    Process.GetProcessById(cloneProcessId).Kill();
                }
                catch (Win32Exception)
                {
                }

                Marshal.FreeHGlobal(callbackParam);
                GC.KeepAlive(callbackDelegate);

                if (hr == 0)
                {
                    Console.WriteLine($"MiniDumpWriteDump failed. ({Marshal.GetHRForLastWin32Error()})");
                    return(hr);
                }
            }

            sw.Stop();
            Console.WriteLine($"Minidump Creation Time: {sw.ElapsedMilliseconds}ms");

            return(0);
        }