Skip to content

Commit 3715e22

Browse files
author
gc46
authored
Merge pull request #1386 from microsoft/main
Merge main into 'release-cpptools' for v1.15.0
2 parents 1e5e292 + 153a9e5 commit 3715e22

15 files changed

Lines changed: 305 additions & 103 deletions

File tree

src/AndroidDebugLauncher/Launcher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ private LaunchOptions SetupForDebuggingWorker(CancellationToken token)
459459

460460
launchOptions.DebuggerMIMode = MIMode.Gdb;
461461

462-
launchOptions.VisualizerFile = "Microsoft.Android.natvis";
462+
launchOptions.VisualizerFiles.Add("Microsoft.Android.natvis");
463463
launchOptions.WaitDynamicLibLoad = _launchOptions.WaitDynamicLibLoad;
464464

465465
return launchOptions;

src/DebugEngineHost/HostNatvisProject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore config
104104
IDisposable disposable = rmw.CurrentMonitor;
105105

106106
// Watch NatvisDiagnostic section
107-
rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(natvisDiagnosticSection, natvisLogger));
107+
rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(checkForSection, natvisLogger));
108108

109109
disposable.Dispose();
110110
}

src/DebugEngineHost/RegistryMonitor.cs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,15 @@ private static extern int RegNotifyChangeKeyValue(SafeRegistryHandle hKey, bool
4747

4848
#endregion
4949

50-
private HostConfigurationSection _section;
50+
private readonly HostConfigurationSection _section;
5151
private readonly bool _watchSubtree;
5252

53-
// Set when registry value is changed
54-
private AutoResetEvent m_changeEvent;
55-
5653
// Set when monitoring is stopped
57-
private AutoResetEvent m_stoppedEvent;
54+
private AutoResetEvent _stoppedEvent;
55+
56+
// Members to handle multiple stop calls.
57+
private bool _isStopped = false;
58+
private readonly object _stopLock = new object();
5859

5960
/// <summary>
6061
/// Occurs when the specified registry key has changed.
@@ -80,9 +81,13 @@ public void Start()
8081

8182
public void Stop()
8283
{
83-
if (m_stoppedEvent != null)
84+
lock (_stopLock)
8485
{
85-
m_stoppedEvent.Set();
86+
if (!_isStopped)
87+
{
88+
_stoppedEvent?.Set();
89+
_isStopped = true;
90+
}
8691
}
8792
}
8893

@@ -93,53 +98,52 @@ private void Monitor()
9398
bool stopped = false;
9499
try
95100
{
96-
m_stoppedEvent = new AutoResetEvent(false);
97-
m_changeEvent = new AutoResetEvent(false);
98-
99-
IntPtr handle = m_changeEvent.SafeWaitHandle.DangerousGetHandle();
100-
101-
int errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
102-
if (errorCode != 0) // 0 is ERROR_SUCCESS
103-
{
104-
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
105-
}
106-
else
101+
_stoppedEvent = new AutoResetEvent(false);
102+
using (AutoResetEvent registryChangedEvent = new AutoResetEvent(false))
107103
{
108-
while (!stopped)
109-
{
110-
int waitResult = WaitHandle.WaitAny(new WaitHandle[] { m_stoppedEvent, m_changeEvent });
104+
IntPtr handle = registryChangedEvent.SafeWaitHandle.DangerousGetHandle();
111105

112-
if (waitResult == 0)
113-
{
114-
stopped = true;
115-
}
116-
else
106+
int errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
107+
if (errorCode != 0) // 0 is ERROR_SUCCESS
108+
{
109+
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
110+
}
111+
else
112+
{
113+
while (!stopped)
117114
{
118-
errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
119-
if (errorCode != 0) // 0 is ERROR_SUCCESS
115+
int waitResult = WaitHandle.WaitAny(new WaitHandle[] { _stoppedEvent, registryChangedEvent });
116+
117+
if (waitResult == 0)
120118
{
121-
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
122-
break;
119+
stopped = true;
120+
}
121+
else
122+
{
123+
errorCode = RegNotifyChangeKeyValue(_section.Handle, _watchSubtree, RegChangeNotifyFilter.REG_NOTIFY_CHANGE_NAME | RegChangeNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET, handle, true);
124+
if (errorCode != 0) // 0 is ERROR_SUCCESS
125+
{
126+
_nativsLogger?.WriteLine(LogLevel.Error, Resource.Error_WatchRegistry, errorCode);
127+
break;
128+
}
129+
RegChanged?.Invoke(this, null);
123130
}
124-
RegChanged?.Invoke(this, null);
125131
}
126132
}
127133
}
128134
}
129135
finally
130136
{
131-
_section.Dispose();
132-
m_stoppedEvent?.Dispose();
133-
m_changeEvent?.Dispose();
137+
_stoppedEvent.Dispose();
138+
_stoppedEvent = null;
134139

135-
m_stoppedEvent = null;
136-
m_changeEvent = null;
140+
_section.Dispose();
137141
}
138142
}
139143

140144
public void Dispose()
141145
{
142-
m_stoppedEvent?.Dispose();
146+
Stop(); // Stopping the monitor will dispose of the AutoResetEvent and HostConfigurationSection
143147
}
144148
}
145149
}

src/MICore/JsonLaunchOptions.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ public abstract partial class BaseOptions
3939
public string TargetArchitecture { get; set; }
4040

4141
/// <summary>
42-
/// .natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see "showDisplayString" if using this setting.
42+
/// .natvis files to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see "showDisplayString" if using this setting.
4343
/// </summary>
4444
[JsonProperty("visualizerFile", DefaultValueHandling = DefaultValueHandling.Ignore)]
45-
public string VisualizerFile { get; set; }
45+
[JsonConverter(typeof(VisualizerFileConverter))]
46+
public List<string> VisualizerFile { get; set; }
4647

4748
/// <summary>
4849
/// When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.
@@ -123,6 +124,37 @@ public abstract partial class BaseOptions
123124
public UnknownBreakpointHandling? UnknownBreakpointHandling { get; set; }
124125
}
125126

127+
internal class VisualizerFileConverter : JsonConverter
128+
{
129+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
130+
{
131+
List<string> visualizerFile = new List<string>();
132+
if (reader.TokenType == JsonToken.StartArray)
133+
{
134+
visualizerFile = serializer.Deserialize<List<string>>(reader);
135+
}
136+
else if (reader.TokenType == JsonToken.String)
137+
{
138+
visualizerFile.Add(reader.Value.ToString());
139+
}
140+
else
141+
{
142+
throw new JsonReaderException(MICoreResources.Error_IncorrectVisualizerFileFormat);
143+
}
144+
return visualizerFile;
145+
}
146+
147+
public override bool CanConvert(Type objectType)
148+
{
149+
throw new NotImplementedException();
150+
}
151+
152+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
153+
{
154+
throw new NotImplementedException();
155+
}
156+
}
157+
126158
public partial class AttachOptions : BaseOptions
127159
{
128160
#region Public Properties for Serialization
@@ -144,7 +176,7 @@ public AttachOptions(
144176
int processId,
145177
string type = null,
146178
string targetArchitecture = null,
147-
string visualizerFile = null,
179+
List<string> visualizerFile = null,
148180
bool? showDisplayString = null,
149181
string additionalSOLibSearchPath = null,
150182
string MIMode = null,
@@ -408,7 +440,7 @@ public LaunchOptions(
408440
List<SetupCommand> postRemoteConnectCommands = null,
409441
List<SetupCommand> customLaunchSetupCommands = null,
410442
LaunchCompleteCommand? launchCompleteCommand = null,
411-
string visualizerFile = null,
443+
List<string> visualizerFile = null,
412444
bool? showDisplayString = null,
413445
List<Environment> environment = null,
414446
string additionalSOLibSearchPath = null,

src/MICore/LaunchOptions.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -960,19 +960,10 @@ public string AdditionalSOLibSearchPath
960960
}
961961
}
962962

963-
private string _visualizerFile;
964963
/// <summary>
965-
/// [Optional] Natvis file name - from install location
964+
/// Collection of natvis files to use when evaluating
966965
/// </summary>
967-
public string VisualizerFile
968-
{
969-
get { return _visualizerFile; }
970-
set
971-
{
972-
VerifyCanModifyProperty(nameof(VisualizerFile));
973-
_visualizerFile = value;
974-
}
975-
}
966+
public List<string> VisualizerFiles { get; } = new List<string>();
976967

977968
private bool _waitDynamicLibLoad = true;
978969
/// <summary>
@@ -1579,9 +1570,9 @@ private void Merge(AttachOptionsForConnection suppOptions)
15791570
{
15801571
DebugChildProcesses = suppOptions.DebugChildProcesses;
15811572
}
1582-
if (string.IsNullOrWhiteSpace(VisualizerFile))
1573+
if (!this.VisualizerFiles.Contains(suppOptions.VisualizerFile))
15831574
{
1584-
VisualizerFile = suppOptions.VisualizerFile;
1575+
this.VisualizerFiles.Add(suppOptions.VisualizerFile);
15851576
}
15861577
if (suppOptions.ShowDisplayStringSpecified)
15871578
{
@@ -1771,7 +1762,10 @@ protected void InitializeCommonOptions(Json.LaunchOptions.BaseOptions options)
17711762
this.TargetArchitecture = ConvertTargetArchitectureAttribute(options.TargetArchitecture);
17721763
}
17731764

1774-
this.VisualizerFile = options.VisualizerFile;
1765+
if (options.VisualizerFile != null && options.VisualizerFile.Count > 0)
1766+
{
1767+
this.VisualizerFiles.AddRange(options.VisualizerFile);
1768+
}
17751769
this.ShowDisplayString = options.ShowDisplayString.GetValueOrDefault(false);
17761770

17771771
this.AdditionalSOLibSearchPath = String.IsNullOrEmpty(this.AdditionalSOLibSearchPath) ?
@@ -1841,8 +1835,8 @@ protected void InitializeCommonOptions(Xml.LaunchOptions.BaseLaunchOptions sourc
18411835
if (string.IsNullOrEmpty(this.WorkingDirectory))
18421836
this.WorkingDirectory = source.WorkingDirectory;
18431837

1844-
if (string.IsNullOrEmpty(this.VisualizerFile))
1845-
this.VisualizerFile = source.VisualizerFile;
1838+
if (!string.IsNullOrEmpty(source.VisualizerFile))
1839+
this.VisualizerFiles.Add(source.VisualizerFile);
18461840

18471841
this.ShowDisplayString = source.ShowDisplayString;
18481842
this.WaitDynamicLibLoad = source.WaitDynamicLibLoad;

src/MICore/MICoreResources.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/MICore/MICoreResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,7 @@ Error: {1}</value>
326326
<data name="Error_SourceFileMapInvalidEditorPath" xml:space="preserve">
327327
<value>'editorPath' can not be null or empty</value>
328328
</data>
329+
<data name="Error_IncorrectVisualizerFileFormat" xml:space="preserve">
330+
<value>'visualizerFile' must be a string or array of strings.</value>
331+
</data>
329332
</root>

src/MICoreUnitTests/BasicLaunchOptionsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ internal void VerifyCoreApisPresent()
263263
launchOptions.WorkingDirectory = "/home/user";
264264
launchOptions.DebuggerMIMode = MIMode.Gdb;
265265
launchOptions.WaitDynamicLibLoad = false;
266-
launchOptions.VisualizerFile = @"c:\myproject\file.natvis";
266+
launchOptions.VisualizerFiles.Add(@"c:\myproject\file.natvis");
267267
launchOptions.SourceMap = new ReadOnlyCollection<SourceMapEntry>(new List<SourceMapEntry>());
268268
launchOptions.Environment = new ReadOnlyCollection<EnvironmentEntry>(new List<EnvironmentEntry>());
269269
Microsoft.DebugEngineHost.HostConfigurationStore configStore = null;

src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ private async Task EnsureModulesLoaded()
543543
public async Task Initialize(HostWaitLoop waitLoop, CancellationToken token)
544544
{
545545
bool success = false;
546-
Natvis.Initialize(_launchOptions.VisualizerFile);
546+
Natvis.Initialize(_launchOptions.VisualizerFiles);
547547
int total = 1;
548548

549549
await this.WaitForConsoleDebuggerInitialize(token);

0 commit comments

Comments
 (0)