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); } }
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(); } } }
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); } }