示例#1
0
        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();
        }
示例#2
0
        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();
        }
示例#3
0
        public void Dump(int pid, DumpType dumpType, 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 {x:8}", _pid, Marshal.GetLastWin32Error()));
            }

            _dumpFileStream = new FileStream(fileName, FileMode.Create);

            var exceptionParam  = new MINIDUMP_EXCEPTION_INFORMATION();
            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,
                ref exceptionParam,
                ref userStreamParam,
                ref callbackParam
                );

            if (!success)
            {
                throw new ApplicationException(String.Format("Error writing dump, error {0:x8}", Marshal.GetLastWin32Error()));
            }

            _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();
        }
示例#4
0
        public void Dump(int pid, DumpType dumpType, 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 {x:8}", _pid, Marshal.GetLastWin32Error()));

            _dumpFileStream = new FileStream(fileName, FileMode.Create);

            var exceptionParam = new MINIDUMP_EXCEPTION_INFORMATION();
            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,
                ref exceptionParam,
                ref userStreamParam,
                ref callbackParam
                );
            if (!success)
                throw new ApplicationException(String.Format("Error writing dump, error {0:x8}", Marshal.GetLastWin32Error()));

            _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();
        }
示例#5
0
        public void DumpOnException(uint threadId, EXCEPTION_RECORD ev)
        {
            if (ev.ExceptionCode == BREAKPOINT_CODE) {
                return;
            }
            if (ev.ExceptionCode == CLRDBG_NOTIFICATION_EXCEPTION_CODE) {
                // based on https://social.msdn.microsoft.com/Forums/vstudio/en-US/bca092d4-d2b5-49ef-8bbc-cbce2c67aa89/net-40-firstchance-exception-0x04242420?forum=clr
                // it's a "notification exception" and can be safely ignored
                return;
            }
            if (ev.ExceptionCode == CTRL_C_EXCEPTION_CODE) {
                // we will also ignore CTRL+C events
                return;
            }
            // print information about the exception (decode it)
            ClrException managedException = null;
            foreach (var clrver in target.ClrVersions) {
                var runtime = clrver.CreateRuntime();
                var thr = runtime.Threads.FirstOrDefault(t => t.OSThreadId == threadId);
                if (thr != null) {
                    managedException = thr.CurrentException;
                    break;
                }
            }
            var exceptionInfo = string.Format("{0:X}.{1} (\"{2}\")", ev.ExceptionCode,
                managedException != null ? managedException.Type.Name : "Native",
                managedException != null ? managedException.Message : "N/A");

            PrintTrace("Exception: " + exceptionInfo);

            if (rgxFilter.IsMatch(exceptionInfo)) {
                byte[] threadContext = new byte[Native.CONTEXT_SIZE];
                target.DataReader.GetThreadContext(threadId, 0, Native.CONTEXT_SIZE, threadContext);
                IntPtr pev = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(EXCEPTION_RECORD)));
                Marshal.StructureToPtr(new EXCEPTION_RECORD{
                    ExceptionAddress = ev.ExceptionAddress,
                    ExceptionFlags = ev.ExceptionFlags,
                    ExceptionCode = ev.ExceptionCode,
                    ExceptionRecord = IntPtr.Zero,
                    NumberParameters = ev.NumberParameters,
                    ExceptionInformation = ev.ExceptionInformation
                }, pev, false);
                var excpointers = new EXCEPTION_POINTERS {
                    ExceptionRecord = pev,
                    ContextRecord = threadContext
                };
                IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(excpointers));
                Marshal.StructureToPtr(excpointers, ptr, false);
                var excinfo = new MINIDUMP_EXCEPTION_INFORMATION() {
                    ThreadId = threadId,
                    ClientPointers = false,
                    ExceptionPointers = ptr
                };
                var pexcinfo = Marshal.AllocHGlobal(Marshal.SizeOf(excinfo));
                Marshal.StructureToPtr(excinfo, pexcinfo, false);

                MakeActualDump(pexcinfo);

                Marshal.FreeHGlobal(pev);
                Marshal.FreeHGlobal(pexcinfo);
                Marshal.FreeHGlobal(ptr);
            }
        }