Skip to content

Commit 5baeadb

Browse files
wiktorkjander-msft
andauthored
Support resetting state when connecting to a previously monitored app (#8154)
* Support resetting state when connecting to a previously monitored app * Fix switch build issue * Fix unit tests * PR Feedback * Add exception startup collection enablement * Fix env check * PR feedback * PR feedback * Use an interlocked many reader single writer to synchronize exceptions threads and pipeline stop calls * Fixup PR tests * PR feedback * PR feedback Co-authored-by: Justin Anderson <[email protected]> * Fixup schema * Unit test * (test) --------- Co-authored-by: Justin Anderson <[email protected]>
1 parent 19f6b56 commit 5baeadb

File tree

31 files changed

+520
-81
lines changed

31 files changed

+520
-81
lines changed

cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"hresult",
5656
"Hsts",
5757
"Impls",
58+
"inproc",
5859
"JITID",
5960
"JWTs",
6061
"LCID",
@@ -107,6 +108,7 @@
107108
"ukwn",
108109
"uninitialize",
109110
"Uninstallation",
111+
"uninstrumented",
110112
"uniquifier",
111113
"Unlocalized",
112114
"Unredacted",

documentation/schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,14 @@
11231123
"$ref": "#/definitions/ExceptionsConfiguration"
11241124
}
11251125
]
1126+
},
1127+
"CollectOnStartup": {
1128+
"type": [
1129+
"boolean",
1130+
"null"
1131+
],
1132+
"description": "[Experimental] Determines if exception collection should begin immediately",
1133+
"default": true
11261134
}
11271135
}
11281136
},

src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,11 @@ public sealed class ExceptionsOptions :
2727
ResourceType = typeof(OptionsDisplayStrings),
2828
Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_CollectionFilters))]
2929
public ExceptionsConfiguration? CollectionFilters { get; set; }
30+
31+
[Display(
32+
ResourceType = typeof(OptionsDisplayStrings),
33+
Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_CollectOnStartup))]
34+
[DefaultValue(ExceptionsOptionsDefaults.CollectOnStartup)]
35+
public bool? CollectOnStartup { get; set; }
3036
}
3137
}

src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptionsDefaults.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ internal static class ExceptionsOptionsDefaults
88
public const bool Enabled = true;
99

1010
public const int TopLevelLimit = 20;
11+
12+
public const bool CollectOnStartup = true;
1113
}
1214
}

src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptionsExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,10 @@ public static int GetTopLevelLimit(this ExceptionsOptions options)
1414
{
1515
return options.TopLevelLimit.GetValueOrDefault(ExceptionsOptionsDefaults.TopLevelLimit);
1616
}
17+
18+
public static bool CollectOnStartup(this ExceptionsOptions options)
19+
{
20+
return options.CollectOnStartup.GetValueOrDefault(ExceptionsOptionsDefaults.CollectOnStartup);
21+
}
1722
}
1823
}

src/Microsoft.Diagnostics.Monitoring.Options/OptionsDisplayStrings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.Diagnostics.Monitoring.Options/OptionsDisplayStrings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,4 +780,7 @@
780780
<value>Performs a match based on the name of the managed entry point assembly of the process.</value>
781781
<comment>The description provided for the ManagedEntryPointAssemblyName parameter on ProcessFilterDescriptor.</comment>
782782
</data>
783+
<data name="DisplayAttributeDescription_ExceptionsOptions_CollectOnStartup" xml:space="preserve">
784+
<value>[Experimental] Determines if exception collection should begin immediately</value>
785+
</data>
783786
</root>

src/Microsoft.Diagnostics.Monitoring.StartupHook/DiagnosticsBootstrapper.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ internal sealed class DiagnosticsBootstrapper :
2323
public DiagnosticsBootstrapper()
2424
{
2525
_exceptionProcessor = new(ToolIdentifiers.IsEnvVarEnabled(InProcessFeaturesIdentifiers.EnvironmentVariables.Exceptions.IncludeMonitorExceptions));
26-
_exceptionProcessor.Start();
26+
27+
// If collectOnStart is not set, assume the default value (true).
28+
string? collectOnStart = Environment.GetEnvironmentVariable(InProcessFeaturesIdentifiers.EnvironmentVariables.Exceptions.CollectOnStartup);
29+
if (collectOnStart == null || ToolIdentifiers.IsEnvVarValueEnabled(collectOnStart))
30+
{
31+
_exceptionProcessor.Start();
32+
}
2733

2834
using IDisposable _ = MonitorExecutionContextTracker.MonitorScope();
2935

@@ -35,6 +41,17 @@ public DiagnosticsBootstrapper()
3541
SharedInternals.MessageDispatcher = new MessageDispatcher.MonitorMessageDispatcher(
3642
new MessageDispatcher.ProfilerMessageSource(CommandSet.StartupHook));
3743
ToolIdentifiers.EnableEnvVar(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.ManagedMessaging);
44+
45+
SharedInternals.MessageDispatcher.RegisterCallback<EmptyPayload>(StartupHookCommand.StopAllFeatures, (IpcMessage) =>
46+
{
47+
_exceptionProcessor.Stop();
48+
_parameterCapturingService?.RequestStopAll();
49+
});
50+
51+
SharedInternals.MessageDispatcher.RegisterCallback<EmptyPayload>(StartupHookCommand.StartAllFeatures, (IpcMessage) =>
52+
{
53+
_exceptionProcessor.Start();
54+
});
3855
}
3956

4057
if (ToolIdentifiers.IsEnvVarEnabled(InProcessFeaturesIdentifiers.EnvironmentVariables.ParameterCapturing.Enable))

src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/CurrentAppDomainExceptionProcessor.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ internal sealed class CurrentAppDomainExceptionProcessor : IDisposable
1414
private readonly ExceptionIdSource _idSource = new();
1515

1616
private readonly CurrentAppDomainFirstChanceExceptionSource _firstChanceSource;
17-
private readonly ExceptionPipeline _firstChancePipeline;
17+
private ExceptionPipeline _firstChancePipeline;
1818

1919
private readonly CurrentAppDomainUnhandledExceptionSource _unhandledSource;
20-
private readonly ExceptionPipeline _unhandledPipeline;
20+
private ExceptionPipeline _unhandledPipeline;
2121

2222
private readonly bool _includeMonitorExceptions;
2323

@@ -35,7 +35,23 @@ public CurrentAppDomainExceptionProcessor(bool includeMonitorExceptions)
3535
public void Start()
3636
{
3737
_firstChancePipeline.Start();
38+
_firstChanceSource.Start();
39+
3840
_unhandledPipeline.Start();
41+
_unhandledSource.Start();
42+
}
43+
44+
public void Stop()
45+
{
46+
// Stop all exception flow from the sources. This will allow draining the pipelines.
47+
_firstChanceSource.Stop();
48+
_unhandledSource.Stop();
49+
_firstChancePipeline.Stop();
50+
_unhandledPipeline.Stop();
51+
52+
// We reset the pipelines entirely to allow their cache to be cleared
53+
_firstChancePipeline = new(_firstChanceSource, ConfigureFirstChancePipeline);
54+
_unhandledPipeline = new(_unhandledSource, ConfigureUnhandledPipeline);
3955
}
4056

4157
private void ConfigureFirstChancePipeline(ExceptionPipelineBuilder builder)

src/Microsoft.Diagnostics.Monitoring.StartupHook/Exceptions/CurrentAppDomainFirstChanceExceptionSource.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ internal sealed class CurrentAppDomainFirstChanceExceptionSource :
1515
{
1616
private long _disposedState;
1717

18-
public CurrentAppDomainFirstChanceExceptionSource()
18+
public override void Start()
1919
{
2020
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
2121
}
2222

23+
public override void Stop()
24+
{
25+
AppDomain.CurrentDomain.FirstChanceException -= CurrentDomain_FirstChanceException;
26+
}
27+
2328
private void CurrentDomain_FirstChanceException(object? sender, FirstChanceExceptionEventArgs e)
2429
{
2530
RaiseExceptionGuarded(e.Exception);

0 commit comments

Comments
 (0)