Skip to content

Commit 336278c

Browse files
Lessley Denningtonldennington
authored andcommitted
trace2: add child_start and child_exit events
Write the TRACE2 child_start and child_exit events for each child process invoked by GCM.
1 parent 9fdda33 commit 336278c

File tree

9 files changed

+253
-23
lines changed

9 files changed

+253
-23
lines changed

src/shared/Core/Authentication/AuthenticationBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected internal virtual async Task<IDictionary<string, string>> InvokeHelperA
4343
// authentication helper's messages.
4444
Context.Trace.Flush();
4545

46-
var process = ChildProcess.Start(Context.Trace2, procStartInfo);
46+
var process = ChildProcess.Start(Context.Trace2, procStartInfo, Trace2ProcessClass.UIHelper);
4747
if (process is null)
4848
{
4949
throw new Exception($"Failed to start helper process: {path} {args}");

src/shared/Core/ChildProcess.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class ChildProcess : DisposableObject
1111

1212
private DateTimeOffset _startTime;
1313
private DateTimeOffset _exitTime => Process.ExitTime;
14+
private ProcessStartInfo _startInfo => Process.StartInfo;
1415

1516
private int _id => Process.Id;
1617

@@ -19,25 +20,37 @@ public class ChildProcess : DisposableObject
1920
public StreamWriter StandardInput => Process.StandardInput;
2021
public StreamReader StandardOutput => Process.StandardOutput;
2122
public StreamReader StandardError => Process.StandardError;
22-
public int Id => Process.Id;
2323
public int ExitCode => Process.ExitCode;
2424

25-
public static ChildProcess Start(ITrace2 trace2, ProcessStartInfo startInfo)
25+
public static ChildProcess Start(ITrace2 trace2, ProcessStartInfo startInfo, Trace2ProcessClass processClass)
2626
{
2727
var childProc = new ChildProcess(trace2, startInfo);
28-
childProc.Start();
28+
childProc.Start(processClass);
2929
return childProc;
3030
}
3131

3232
public ChildProcess(ITrace2 trace2, ProcessStartInfo startInfo)
3333
{
3434
_trace2 = trace2;
3535
Process = new Process() { StartInfo = startInfo };
36+
Process.Exited += ProcessOnExited;
3637
}
3738

38-
public void Start()
39+
public void Start(Trace2ProcessClass processClass)
3940
{
4041
ThrowIfDisposed();
42+
// Record the time just before the process starts, since:
43+
// (1) There is no event related to Start as there is with Exit.
44+
// (2) Using Process.StartTime causes a race condition that leads
45+
// to an exception if the process finishes executing before the
46+
// variable is passed to Trace2.
47+
_startTime = DateTimeOffset.UtcNow;
48+
_trace2.WriteChildStart(
49+
_startTime,
50+
processClass,
51+
_startInfo.UseShellExecute,
52+
_startInfo.FileName,
53+
_startInfo.Arguments);
4154
Process.Start();
4255
}
4356

@@ -47,7 +60,20 @@ public void Start()
4760

4861
protected override void ReleaseManagedResources()
4962
{
63+
Process.Exited -= ProcessOnExited;
5064
Process.Dispose();
5165
base.ReleaseUnmanagedResources();
5266
}
67+
68+
private void ProcessOnExited(object sender, EventArgs e)
69+
{
70+
if (sender is Process)
71+
{
72+
double elapsedTime = (_exitTime - _startTime).TotalSeconds;
73+
_trace2.WriteChildExit(
74+
elapsedTime,
75+
_id,
76+
Process.ExitCode);
77+
}
78+
}
5379
}

src/shared/Core/Diagnostics/GitDiagnostic.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ protected override Task<bool> RunInternalAsync(StringBuilder log, IList<string>
2525

2626
log.Append("Listing all Git configuration...");
2727
ChildProcess configProc = CommandContext.Git.CreateProcess("config --list --show-origin");
28-
configProc.Start();
28+
configProc.Start(Trace2ProcessClass.Git);
2929
// To avoid deadlocks, always read the output stream first and then wait
3030
// TODO: don't read in all the data at once; stream it
3131
string gitConfig = configProc.StandardOutput.ReadToEnd().TrimEnd();

src/shared/Core/Git.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public GitVersion Version
9090
{
9191
using (var git = CreateProcess("version"))
9292
{
93-
git.Start();
93+
git.Start(Trace2ProcessClass.Git);
9494

9595
string data = git.StandardOutput.ReadToEnd();
9696
git.WaitForExit();
@@ -120,7 +120,7 @@ public string GetCurrentRepository()
120120
{
121121
using (var git = CreateProcess("rev-parse --absolute-git-dir"))
122122
{
123-
git.Start();
123+
git.Start(Trace2ProcessClass.Git);
124124
string data = git.StandardOutput.ReadToEnd();
125125
git.WaitForExit();
126126

@@ -141,7 +141,7 @@ public IEnumerable<GitRemote> GetRemotes()
141141
{
142142
using (var git = CreateProcess("remote -v show"))
143143
{
144-
git.Start();
144+
git.Start(Trace2ProcessClass.Git);
145145
// To avoid deadlocks, always read the output stream first and then wait
146146
// TODO: don't read in all the data at once; stream it
147147
string data = git.StandardOutput.ReadToEnd();

src/shared/Core/GitConfiguration.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public void Enumerate(GitConfigurationLevel level, GitConfigurationEnumerationCa
129129
string levelArg = GetLevelFilterArg(level);
130130
using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} --list"))
131131
{
132-
git.Start();
132+
git.Start(Trace2ProcessClass.Git);
133133
// To avoid deadlocks, always read the output stream first and then wait
134134
// TODO: don't read in all the data at once; stream it
135135
string data = git.StandardOutput.ReadToEnd();
@@ -198,7 +198,7 @@ public bool TryGet(GitConfigurationLevel level, GitConfigurationType type, strin
198198
string typeArg = GetCanonicalizeTypeArg(type);
199199
using (ChildProcess git = _git.CreateProcess($"config --null {levelArg} {typeArg} {QuoteCmdArg(name)}"))
200200
{
201-
git.Start();
201+
git.Start(Trace2ProcessClass.Git);
202202
// To avoid deadlocks, always read the output stream first and then wait
203203
// TODO: don't read in all the data at once; stream it
204204
string data = git.StandardOutput.ReadToEnd();
@@ -236,7 +236,7 @@ public void Set(GitConfigurationLevel level, string name, string value)
236236
string levelArg = GetLevelFilterArg(level);
237237
using (ChildProcess git = _git.CreateProcess($"config {levelArg} {QuoteCmdArg(name)} {QuoteCmdArg(value)}"))
238238
{
239-
git.Start();
239+
git.Start(Trace2ProcessClass.Git);
240240
git.WaitForExit();
241241

242242
switch (git.ExitCode)
@@ -257,7 +257,7 @@ public void Add(GitConfigurationLevel level, string name, string value)
257257
string levelArg = GetLevelFilterArg(level);
258258
using (ChildProcess git = _git.CreateProcess($"config {levelArg} --add {QuoteCmdArg(name)} {QuoteCmdArg(value)}"))
259259
{
260-
git.Start();
260+
git.Start(Trace2ProcessClass.Git);
261261
git.WaitForExit();
262262

263263
switch (git.ExitCode)
@@ -278,7 +278,7 @@ public void Unset(GitConfigurationLevel level, string name)
278278
string levelArg = GetLevelFilterArg(level);
279279
using (ChildProcess git = _git.CreateProcess($"config {levelArg} --unset {QuoteCmdArg(name)}"))
280280
{
281-
git.Start();
281+
git.Start(Trace2ProcessClass.Git);
282282
git.WaitForExit();
283283

284284
switch (git.ExitCode)
@@ -302,7 +302,7 @@ public IEnumerable<string> GetAll(GitConfigurationLevel level, GitConfigurationT
302302

303303
using (ChildProcess git = _git.CreateProcess(gitArgs))
304304
{
305-
git.Start();
305+
git.Start(Trace2ProcessClass.Git);
306306
// To avoid deadlocks, always read the output stream first and then wait
307307
// TODO: don't read in all the data at once; stream it
308308
string data = git.StandardOutput.ReadToEnd();
@@ -344,7 +344,7 @@ public IEnumerable<string> GetRegex(GitConfigurationLevel level, GitConfiguratio
344344

345345
using (ChildProcess git = _git.CreateProcess(gitArgs))
346346
{
347-
git.Start();
347+
git.Start(Trace2ProcessClass.Git);
348348
// To avoid deadlocks, always read the output stream first and then wait
349349
// TODO: don't read in all the data at once; stream it
350350
string data = git.StandardOutput.ReadToEnd();
@@ -386,7 +386,7 @@ public void ReplaceAll(GitConfigurationLevel level, string name, string valueReg
386386

387387
using (ChildProcess git = _git.CreateProcess(gitArgs))
388388
{
389-
git.Start();
389+
git.Start(Trace2ProcessClass.Git);
390390
git.WaitForExit();
391391

392392
switch (git.ExitCode)
@@ -413,7 +413,7 @@ public void UnsetAll(GitConfigurationLevel level, string name, string valueRegex
413413

414414
using (ChildProcess git = _git.CreateProcess(gitArgs))
415415
{
416-
git.Start();
416+
git.Start(Trace2ProcessClass.Git);
417417
git.WaitForExit();
418418

419419
switch (git.ExitCode)

src/shared/Core/PlatformUtils.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ private static string GetOSVersion(ITrace2 trace2)
338338

339339
using (var swvers = new ChildProcess(trace2, psi))
340340
{
341-
swvers.Start();
341+
swvers.Start(Trace2ProcessClass.Other);
342342
swvers.WaitForExit();
343343

344344
if (swvers.ExitCode == 0)
@@ -359,7 +359,7 @@ private static string GetOSVersion(ITrace2 trace2)
359359

360360
using (var uname = new ChildProcess(trace2, psi))
361361
{
362-
uname.Start();
362+
uname.Start(Trace2ProcessClass.Other);
363363
uname.Process.WaitForExit();
364364

365365
if (uname.ExitCode == 0)

0 commit comments

Comments
 (0)