Beispiel #1
0
        private static void GetMemoryDumpProcDump(Process process, string outputDir)
        {
            var homePath = Environment.GetEnvironmentVariable("HOME");

            ThrowIfDiskOutOfSpace(homePath);
            string       command      = Path.Combine(_cdbFolder, "procdump.exe");
            string       arguments    = " -accepteula -r -ma {0} {1}\\{2}_{3}_{0}.dmp";
            MemoryStream outputStream = null;
            MemoryStream errorStream  = null;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource();
                Console.WriteLine(process.ProcessName + " is " + (process.IsWin64() ? "64" : "32") + "-bit");
                arguments = string.Format(arguments, process.Id, outputDir, Environment.MachineName, process.ProcessName);
                Console.WriteLine("Comand:");
                Console.WriteLine(command + " " + arguments);

                Logger.LogDiagnoserVerboseEvent($"Launching Command : {command} {arguments}");

                var dumpGenerator = new Process()
                {
                    StartInfo =
                    {
                        FileName  = command,
                        Arguments = arguments,
                        //WindowStyle = ProcessWindowStyle.Hidden,
                        UseShellExecute        = false,
                        RedirectStandardError  = true,
                        RedirectStandardOutput = true,
                    }
                };

                outputStream = new MemoryStream();
                errorStream  = new MemoryStream();
                dumpGenerator.Start();

                var tasks = new List <Task>
                {
                    MemoryStreamExtensions.CopyStreamAsync(dumpGenerator.StandardOutput.BaseStream, outputStream, cancellationTokenSource.Token),
                    MemoryStreamExtensions.CopyStreamAsync(dumpGenerator.StandardError.BaseStream, errorStream, cancellationTokenSource.Token)
                };

                string processMemoryConsumption = string.Empty;
                long   processPrivateBytes      = 0;
                try
                {
                    processPrivateBytes      = process.PrivateMemorySize64;
                    processMemoryConsumption = $"{ process.ProcessName} Private Bytes consumption is { ConversionUtils.BytesToString(processPrivateBytes) }";
                }
                catch (Exception)
                {
                }

                long tenGb = (long)10 * 1024 * 1024 * 1024;
                if (processPrivateBytes > tenGb)
                {
                    string message = $"{processMemoryConsumption}. Cancelling dump generation.";
                    Logger.TraceFatal(message, true);
                    Environment.Exit(0);
                }

                Logger.LogDiagnoserVerboseEvent($"Dump Generator started, waiting for it to exit - {processMemoryConsumption}");

                // Keep this process alive untile the dump has been collected
                int sleepCount = 0;
                while (!dumpGenerator.HasExited)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                    ++sleepCount;
                    if (sleepCount == 30)
                    {
                        sleepCount = 0;
                        Logger.LogDiagnoserVerboseEvent($"Waiting for Dump Generator invoked with args ({arguments}) to finish");
                    }
                }

                Task.WhenAll(tasks);

                string output         = outputStream.ReadToEnd();
                string error          = errorStream.ReadToEnd();
                string procDumpOutput = output;
                if (!string.IsNullOrWhiteSpace(error))
                {
                    procDumpOutput += Environment.NewLine + "Error Stream Output" + Environment.NewLine + "-----------------" + Environment.NewLine + error;
                }
                Logger.LogDiagnoserVerboseEvent(procDumpOutput);

                if (output.ToLower().Contains("Dump 1 complete".ToLower()))
                {
                    Logger.LogDiagnoserVerboseEvent($"Procdump completed successfully.  Detailed ProcDump output: {Environment.NewLine} {procDumpOutput}");
                    Logger.LogStatus($"Collected dump of {process.ProcessName} ({ process.Id })");
                }
                else
                {
                    Logger.TraceFatal($"ProcDump failed to run. Detailed ProcDump output: {Environment.NewLine} {procDumpOutput}");
                }
            }
            catch (Exception ex)
            {
                Logger.LogDiagnoserErrorEvent($"Failed in GetMemoryDumpProcDump for arguments:{arguments}", ex);
            }
        }
Beispiel #2
0
        private static ProfileResultInfo ExecuteProfilingCommand(string arguments)
        {
            MemoryStream outputStream = null;
            MemoryStream errorStream  = null;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource();

                Logger.LogDiagnoserVerboseEvent("Launching Profiler Command - ProcessName:" + _processName + "   arguments:" + arguments);

                Process process = new Process();

                ProcessStartInfo pinfo = new ProcessStartInfo
                {
                    Arguments = arguments,
                    FileName  = _processName
                };

                process.StartInfo = pinfo;
                process.StartInfo.UseShellExecute        = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;

                outputStream = new MemoryStream();
                errorStream  = new MemoryStream();

                process.Start();

                var tasks = new List <Task>
                {
                    MemoryStreamExtensions.CopyStreamAsync(process.StandardOutput.BaseStream, outputStream, cancellationTokenSource.Token),
                    MemoryStreamExtensions.CopyStreamAsync(process.StandardError.BaseStream, errorStream, cancellationTokenSource.Token)
                };
                process.WaitForExit();

                Task.WhenAll(tasks);

                string output = outputStream.ReadToEnd();
                string error  = errorStream.ReadToEnd();

                Logger.LogInfo(output);

                if (!string.IsNullOrEmpty(error))
                {
                    Logger.LogInfo(error);
                }

                if (process.ExitCode != 0)
                {
                    Logger.LogDiagnoserErrorEvent(string.Format(CultureInfo.InvariantCulture, "Starting process {0} failed with the following error code '{1}'.", _processName, process.ExitCode), $"process.ExitCode = {process.ExitCode.ToString()}");
                    return(new ProfileResultInfo(HttpStatusCode.InternalServerError, "Profiling process failed with the following error code: " + process.ExitCode));
                }

                else if (!string.IsNullOrEmpty(error))
                {
                    return(new ProfileResultInfo(HttpStatusCode.InternalServerError, "Profiling process failed with the following error: " + error));
                }

                return(new ProfileResultInfo(HttpStatusCode.OK, string.Empty));
            }
            catch (Exception ex)
            {
                Logger.LogDiagnoserErrorEvent($"Executing Commmand {_processName} {arguments} failed", ex);
                return(new ProfileResultInfo(HttpStatusCode.InternalServerError, ex.Message));
            }
            finally
            {
                if (outputStream != null)
                {
                    outputStream.Dispose();
                }

                if (errorStream != null)
                {
                    errorStream.Dispose();
                }
            }
        }
Beispiel #3
0
        private static void CollectStackTracerLog(string zipFolderPath, int processId, bool is64bit)
        {
            try
            {
                var    assemblyDir     = System.Reflection.Assembly.GetEntryAssembly().Location;
                string clrprofilerPath = Path.GetDirectoryName(assemblyDir);
                string stackTracerPath = Path.Combine(clrprofilerPath, "stacktracer");

                if (is64bit)
                {
                    stackTracerPath = Path.Combine(stackTracerPath, "stacktracer64.exe");
                }
                else
                {
                    stackTracerPath = Path.Combine(stackTracerPath, "stacktracer32.exe");
                }

                MemoryStream outputStream = null;
                MemoryStream errorStream  = null;

                var cancellationTokenSource = new CancellationTokenSource();

                Process process = new Process();

                ProcessStartInfo pinfo = new ProcessStartInfo
                {
                    Arguments = $"{processId} {zipFolderPath}",
                    FileName  = stackTracerPath
                };

                Logger.LogDiagnoserEvent($"Starting process:{stackTracerPath} with arguments: {pinfo.Arguments}");

                process.StartInfo = pinfo;
                process.StartInfo.UseShellExecute        = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;

                outputStream = new MemoryStream();
                errorStream  = new MemoryStream();

                process.Start();

                var tasks = new List <Task>
                {
                    MemoryStreamExtensions.CopyStreamAsync(process.StandardOutput.BaseStream, outputStream, cancellationTokenSource.Token),
                    MemoryStreamExtensions.CopyStreamAsync(process.StandardError.BaseStream, errorStream, cancellationTokenSource.Token)
                };
                process.WaitForExit();

                Task.WhenAll(tasks);

                string output = outputStream.ReadToEnd();
                string error  = errorStream.ReadToEnd();

                Logger.LogInfo(output);

                if (!string.IsNullOrEmpty(error))
                {
                    Logger.LogInfo(error);
                }

                if (process.ExitCode != 0)
                {
                    Logger.LogDiagnoserErrorEvent(string.Format(CultureInfo.InvariantCulture, "Starting process {0} failed with the following error code '{1}'.", stackTracerPath, process.ExitCode), $"process.ExitCode = {process.ExitCode.ToString()}");
                }
            }
            catch (Exception ex)
            {
                Logger.LogDiagnoserErrorEvent("Failed while trying to generate raw stack traces using StackTracer", ex);
            }
        }