예제 #1
0
파일: DumpWriter.cs 프로젝트: tiandian/msos
        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
파일: DumpWriter.cs 프로젝트: goldshtn/msos
        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, 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();
        }
예제 #4
0
 /// <summary>
 /// apply the new dump type
 /// </summary>
 private void SetDumpConfig(DumpType dumptype)
 {
     configFile.UpdateAppSetting(AppKeyName.DumpLayer, dumptype.ToString());
 }
 private void ArchiveDump(DumpType dumpType, string fileName)
 {
     if (_settings.ArchiveDumps)
     {
         var archiveDir = Path.Combine(AppContext.BaseDirectory, "dump-archive", dumpType.ToString().ToLower());
         if (!Directory.Exists(archiveDir))
         {
             Directory.CreateDirectory(archiveDir);
         }
         var info            = new FileInfo(fileName);
         var archiveFilename = $"{info.LastWriteTimeUtc.Year}-{info.LastWriteTimeUtc.Month:00}-{info.LastWriteTimeUtc.Day:00}-{dumpType.ToString().ToLower()}.xml.gz";
         var targetFileName  = Path.Combine(archiveDir, archiveFilename);
         _logger.Information("Archiving {@fileName} to {@archiveFileName}", fileName, targetFileName);
         if (File.Exists(fileName))
         {
             File.Copy(fileName, targetFileName);
         }
         else
         {
             _logger.Warning("File ({@fileName}) to archive not found.", fileName);
         }
     }
     else
     {
         _logger.Debug("{@dumpType} dump archiving skipped.", dumpType);
     }
 }
예제 #6
0
        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 {x:8}", _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();
        }
예제 #7
0
        private async Task <ResponseStreamHolder> CaptureDumpAsync(string processQuery, DumpType dumpType, CancellationToken token)
        {
            using HttpRequestMessage request = new(HttpMethod.Get, $"/dump?{processQuery}&type={dumpType.ToString("G")}");
            request.Headers.Add(HeaderNames.Accept, ContentTypes.ApplicationOctetStream);

            using DisposableBox <HttpResponseMessage> responseBox = new(
                      await SendAndLogAsync(
                          request,
                          HttpCompletionOption.ResponseHeadersRead,
                          token).ConfigureAwait(false));

            switch (responseBox.Value.StatusCode)
            {
            case HttpStatusCode.OK:
                ValidateContentType(responseBox.Value, ContentTypes.ApplicationOctetStream);
                return(await ResponseStreamHolder.CreateAsync(responseBox).ConfigureAwait(false));

            case HttpStatusCode.BadRequest:
                ValidateContentType(responseBox.Value, ContentTypes.ApplicationProblemJson);
                throw await CreateValidationProblemDetailsExceptionAsync(responseBox.Value).ConfigureAwait(false);

            case HttpStatusCode.Unauthorized:
            case HttpStatusCode.NotFound:
            case HttpStatusCode.TooManyRequests:
                ThrowIfNotSuccess(responseBox.Value);
                break;
            }

            throw await CreateUnexpectedStatusCodeExceptionAsync(responseBox.Value).ConfigureAwait(false);
        }