Skip to content

Commit

Permalink
Redirect procdump process output to diag files (#2181)
Browse files Browse the repository at this point in the history
* Redirect procdump output to diag log files
vagisha-nidhi authored Sep 19, 2019
1 parent 951216d commit 499b57b
Showing 14 changed files with 77 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ public override int LaunchDataCollector(IDictionary<string, string> environmentV
}

var argumentsString = string.Join(" ", commandLineArguments);
var dataCollectorProcess = this.processHelper.LaunchProcess(dataCollectorProcessPath, argumentsString, Directory.GetCurrentDirectory(), environmentVariables, this.ErrorReceivedCallback, this.ExitCallBack);
var dataCollectorProcess = this.processHelper.LaunchProcess(dataCollectorProcessPath, argumentsString, Directory.GetCurrentDirectory(), environmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) ;
this.DataCollectorProcessId = this.processHelper.GetProcessId(dataCollectorProcess);
return this.DataCollectorProcessId;
}
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ public override int LaunchDataCollector(IDictionary<string, string> environmentV

var cliArgs = string.Join(" ", commandLineArguments);
var argumentsString = string.Format("{0} \"{1}\" {2} ", args, dataCollectorAssemblyPath, cliArgs);
var dataCollectorProcess = this.processHelper.LaunchProcess(currentProcessFileName, argumentsString, Directory.GetCurrentDirectory(), environmentVariables, this.ErrorReceivedCallback, this.ExitCallBack);
var dataCollectorProcess = this.processHelper.LaunchProcess(currentProcessFileName, argumentsString, Directory.GetCurrentDirectory(), environmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null);
this.DataCollectorProcessId = this.processHelper.GetProcessId(dataCollectorProcess);
return this.DataCollectorProcessId;
}
Original file line number Diff line number Diff line change
@@ -42,6 +42,16 @@ public ProcessDumpUtility(IProcessHelper processHelper, IFileHelper fileHelper,
this.nativeMethodsHelper = nativeMethodsHelper;
}

protected Action<object, string> OutputReceivedCallback => (process, data) =>
{
// Log all standard output message of procdump in diag files.
// Otherwise they end up coming on console in pipleine.
if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("ProcessDumpUtility.OutputReceivedCallback: Output received from procdump process: " + data);
}
};

/// <inheritdoc/>
public string GetDumpFile()
{
@@ -101,7 +111,8 @@ public void StartTriggerBasedProcessDump(int processId, string dumpFileGuid, str
testResultsDirectory,
null,
null,
null) as Process;
null,
this.OutputReceivedCallback) as Process;
}

/// <inheritdoc/>
@@ -126,7 +137,8 @@ public void StartHangBasedProcessDump(int processId, string dumpFileGuid, string
testResultsDirectory,
null,
null,
null) as Process;
null,
this.OutputReceivedCallback) as Process;
}

/// <inheritdoc/>
@@ -171,8 +183,8 @@ private string GetProcDumpExecutable(int processId)
}
else
{
filename = this.nativeMethodsHelper.Is64Bit(this.processHelper.GetProcessHandle(processId)) ?
Constants.Procdump64Process : Constants.ProcdumpProcess;
filename = this.nativeMethodsHelper.Is64Bit(this.processHelper.GetProcessHandle(processId)) ?
Constants.Procdump64Process : Constants.ProcdumpProcess;
}

var procDumpExe = Path.Combine(procdumpPath, filename);
Original file line number Diff line number Diff line change
@@ -20,8 +20,9 @@ public interface IProcessHelper
/// <param name="environmentVariables">Environment variables to set while bootstrapping the process.</param>
/// <param name="errorCallback">Call back for to read error stream data</param>
/// <param name="exitCallBack">Call back for on process exit</param>
/// <param name="outputCallback">Call back for on process output</param>
/// <returns>The process created.</returns>
object LaunchProcess(string processPath, string arguments, string workingDirectory, IDictionary<string, string> environmentVariables, Action<object, string> errorCallback, Action<object> exitCallBack);
object LaunchProcess(string processPath, string arguments, string workingDirectory, IDictionary<string, string> environmentVariables, Action<object, string> errorCallback, Action<object> exitCallBack, Action<object, string> outputCallback);

/// <summary>
/// Gets the current process file path.
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions
using System.Diagnostics;
using System.IO;
using System.Reflection;

using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;

/// <summary>
@@ -19,7 +18,7 @@ public partial class ProcessHelper : IProcessHelper
private static readonly string ARM = "arm";

/// <inheritdoc/>
public object LaunchProcess(string processPath, string arguments, string workingDirectory, IDictionary<string, string> envVariables, Action<object, string> errorCallback, Action<object> exitCallBack)
public object LaunchProcess(string processPath, string arguments, string workingDirectory, IDictionary<string, string> envVariables, Action<object, string> errorCallback, Action<object> exitCallBack, Action<object, string> outputCallBack)
{
var process = new Process();
try
@@ -31,6 +30,7 @@ public object LaunchProcess(string processPath, string arguments, string working
process.StartInfo.FileName = processPath;
process.StartInfo.Arguments = arguments;
process.StartInfo.RedirectStandardError = true;

process.EnableRaisingEvents = true;

if (envVariables != null)
@@ -41,6 +41,12 @@ public object LaunchProcess(string processPath, string arguments, string working
}
}

if (outputCallBack != null)
{
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, args) => outputCallBack(sender as Process, args.Data);
}

if (errorCallback != null)
{
process.ErrorDataReceived += (sender, args) => errorCallback(sender as Process, args.Data);
@@ -73,6 +79,11 @@ public object LaunchProcess(string processPath, string arguments, string working
{
process.BeginErrorReadLine();
}

if (outputCallBack != null)
{
process.BeginOutputReadLine();
}
}
catch (Exception)
{
Original file line number Diff line number Diff line change
@@ -19,7 +19,8 @@ public object LaunchProcess(
string workingDirectory,
IDictionary<string, string> environmentVariables,
Action<object, string> errorCallback,
Action<object> exitCallBack)
Action<object> exitCallBack,
Action<object, string> ouputCallBack)
{
throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public object LaunchProcess(
string workingDirectory,
IDictionary<string, string> environmentVariables,
Action<object, string> errorCallback,
Action<object> exitCallBack)
Action<object> exitCallBack,
Action<object, string> outputCallback)
{
throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -370,7 +370,7 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
EqtTrace.Verbose("DefaultTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments);

cancellationToken.ThrowIfCancellationRequested();
this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack) as Process;
this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) as Process;
}
else
{
Original file line number Diff line number Diff line change
@@ -346,7 +346,7 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
EqtTrace.Verbose("DotnetTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments);

cancellationToken.ThrowIfCancellationRequested();
this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack) as Process;
this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) as Process;
}
else
{
Original file line number Diff line number Diff line change
@@ -491,9 +491,10 @@ private void SetUpMocksForDotNetTestHost()
It.IsAny<string>(),
It.IsAny<IDictionary<string, string>>(),
It.IsAny<Action<object, string>>(),
It.IsAny<Action<object>>()))
.Callback<string, string, string, IDictionary<string, string>, Action<object, string>, Action<object>>(
(var1, var2, var3, dictionary, errorCallback, exitCallback) =>
It.IsAny<Action<object>>(),
It.IsAny<Action<object, string>>()))
.Callback<string, string, string, IDictionary<string, string>, Action<object, string>, Action<object>, Action<object, string>>(
(var1, var2, var3, dictionary, errorCallback, exitCallback, outputCallback) =>
{
var process = Process.GetCurrentProcess();

Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ public void LaunchDataCollectorShouldLaunchDataCollectorProcess()
List<string> arguments = new List<string>();
this.dataCollectionLauncher.LaunchDataCollector(null, arguments);

this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>()), Times.Once());
this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>(), It.IsAny<Action<object, string>>()), Times.Once());
}

[TestMethod]
@@ -55,7 +55,7 @@ public void LaunchDataCollectorShouldAppendDoubleQuoteForDataCollectorDllPath()
List<string> arguments = new List<string>();
this.dataCollectionLauncher.LaunchDataCollector(null, arguments);

this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), string.Format("{0} \"{1}\" {2} ", "exec", dataCollectorAssemblyPath, string.Join(" ", arguments)), It.IsAny<string>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>()), Times.Once());
this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), string.Format("{0} \"{1}\" {2} ", "exec", dataCollectorAssemblyPath, string.Join(" ", arguments)), It.IsAny<string>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>(), It.IsAny<Action<object, string>>()), Times.Once());
}

[TestMethod]
@@ -66,7 +66,7 @@ public void LaunchDataCollectorShouldLaunchDataCollectorProcessWithCurrecntWorki

string currentWorkingDirectory = Directory.GetCurrentDirectory();

this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), It.IsAny<string>(), currentWorkingDirectory, It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>()), Times.Once());
this.mockProcessHelper.Verify(x => x.LaunchProcess(It.IsAny<string>(), It.IsAny<string>(), currentWorkingDirectory, It.IsAny<IDictionary<string, string>>(), It.IsAny<Action<object, string>>(), It.IsAny<Action<Object>>(), It.IsAny<Action<object, string>>()), Times.Once());
}
}
}
Loading

0 comments on commit 499b57b

Please sign in to comment.