Skip to content

Commit

Permalink
Merge pull request #1387 from microsoft/main
Browse files Browse the repository at this point in the history
Merge 'main' into 'release_mdd'
  • Loading branch information
gc46 authored Feb 8, 2023
2 parents 8685148 + 153a9e5 commit 1b020d7
Show file tree
Hide file tree
Showing 13 changed files with 263 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/AndroidDebugLauncher/Launcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ private LaunchOptions SetupForDebuggingWorker(CancellationToken token)

launchOptions.DebuggerMIMode = MIMode.Gdb;

launchOptions.VisualizerFile = "Microsoft.Android.natvis";
launchOptions.VisualizerFiles.Add("Microsoft.Android.natvis");
launchOptions.WaitDynamicLibLoad = _launchOptions.WaitDynamicLibLoad;

return launchOptions;
Expand Down
40 changes: 36 additions & 4 deletions src/MICore/JsonLaunchOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ public abstract partial class BaseOptions
public string TargetArchitecture { get; set; }

/// <summary>
/// .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.
/// .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.
/// </summary>
[JsonProperty("visualizerFile", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string VisualizerFile { get; set; }
[JsonConverter(typeof(VisualizerFileConverter))]
public List<string> VisualizerFile { get; set; }

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

internal class VisualizerFileConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
List<string> visualizerFile = new List<string>();
if (reader.TokenType == JsonToken.StartArray)
{
visualizerFile = serializer.Deserialize<List<string>>(reader);
}
else if (reader.TokenType == JsonToken.String)
{
visualizerFile.Add(reader.Value.ToString());
}
else
{
throw new JsonReaderException(MICoreResources.Error_IncorrectVisualizerFileFormat);
}
return visualizerFile;
}

public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

public partial class AttachOptions : BaseOptions
{
#region Public Properties for Serialization
Expand All @@ -144,7 +176,7 @@ public AttachOptions(
int processId,
string type = null,
string targetArchitecture = null,
string visualizerFile = null,
List<string> visualizerFile = null,
bool? showDisplayString = null,
string additionalSOLibSearchPath = null,
string MIMode = null,
Expand Down Expand Up @@ -408,7 +440,7 @@ public LaunchOptions(
List<SetupCommand> postRemoteConnectCommands = null,
List<SetupCommand> customLaunchSetupCommands = null,
LaunchCompleteCommand? launchCompleteCommand = null,
string visualizerFile = null,
List<string> visualizerFile = null,
bool? showDisplayString = null,
List<Environment> environment = null,
string additionalSOLibSearchPath = null,
Expand Down
26 changes: 10 additions & 16 deletions src/MICore/LaunchOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -960,19 +960,10 @@ public string AdditionalSOLibSearchPath
}
}

private string _visualizerFile;
/// <summary>
/// [Optional] Natvis file name - from install location
/// Collection of natvis files to use when evaluating
/// </summary>
public string VisualizerFile
{
get { return _visualizerFile; }
set
{
VerifyCanModifyProperty(nameof(VisualizerFile));
_visualizerFile = value;
}
}
public List<string> VisualizerFiles { get; } = new List<string>();

private bool _waitDynamicLibLoad = true;
/// <summary>
Expand Down Expand Up @@ -1579,9 +1570,9 @@ private void Merge(AttachOptionsForConnection suppOptions)
{
DebugChildProcesses = suppOptions.DebugChildProcesses;
}
if (string.IsNullOrWhiteSpace(VisualizerFile))
if (!this.VisualizerFiles.Contains(suppOptions.VisualizerFile))
{
VisualizerFile = suppOptions.VisualizerFile;
this.VisualizerFiles.Add(suppOptions.VisualizerFile);
}
if (suppOptions.ShowDisplayStringSpecified)
{
Expand Down Expand Up @@ -1771,7 +1762,10 @@ protected void InitializeCommonOptions(Json.LaunchOptions.BaseOptions options)
this.TargetArchitecture = ConvertTargetArchitectureAttribute(options.TargetArchitecture);
}

this.VisualizerFile = options.VisualizerFile;
if (options.VisualizerFile != null && options.VisualizerFile.Count > 0)
{
this.VisualizerFiles.AddRange(options.VisualizerFile);
}
this.ShowDisplayString = options.ShowDisplayString.GetValueOrDefault(false);

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

if (string.IsNullOrEmpty(this.VisualizerFile))
this.VisualizerFile = source.VisualizerFile;
if (!string.IsNullOrEmpty(source.VisualizerFile))
this.VisualizerFiles.Add(source.VisualizerFile);

this.ShowDisplayString = source.ShowDisplayString;
this.WaitDynamicLibLoad = source.WaitDynamicLibLoad;
Expand Down
9 changes: 9 additions & 0 deletions src/MICore/MICoreResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/MICore/MICoreResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,7 @@ Error: {1}</value>
<data name="Error_SourceFileMapInvalidEditorPath" xml:space="preserve">
<value>'editorPath' can not be null or empty</value>
</data>
<data name="Error_IncorrectVisualizerFileFormat" xml:space="preserve">
<value>'visualizerFile' must be a string or array of strings.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/MICoreUnitTests/BasicLaunchOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ internal void VerifyCoreApisPresent()
launchOptions.WorkingDirectory = "/home/user";
launchOptions.DebuggerMIMode = MIMode.Gdb;
launchOptions.WaitDynamicLibLoad = false;
launchOptions.VisualizerFile = @"c:\myproject\file.natvis";
launchOptions.VisualizerFiles.Add(@"c:\myproject\file.natvis");
launchOptions.SourceMap = new ReadOnlyCollection<SourceMapEntry>(new List<SourceMapEntry>());
launchOptions.Environment = new ReadOnlyCollection<EnvironmentEntry>(new List<EnvironmentEntry>());
Microsoft.DebugEngineHost.HostConfigurationStore configStore = null;
Expand Down
2 changes: 1 addition & 1 deletion src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ private async Task EnsureModulesLoaded()
public async Task Initialize(HostWaitLoop waitLoop, CancellationToken token)
{
bool success = false;
Natvis.Initialize(_launchOptions.VisualizerFile);
Natvis.Initialize(_launchOptions.VisualizerFiles);
int total = 1;

await this.WaitForConsoleDebuggerInitialize(token);
Expand Down
83 changes: 48 additions & 35 deletions src/MIDebugEngine/Natvis.Impl/Natvis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ internal Natvis(DebuggedProcess process, bool showDisplayString, HostConfigurati
_configStore = configStore;
}

public void Initialize(string fileName)
private void InitializeNatvisServices()
{
try
{
Expand All @@ -271,52 +271,65 @@ public void Initialize(string fileName)
{
// failed to find the VS Service
}
}

if (!string.IsNullOrEmpty(fileName))
/*
* Handle multiple Natvis files
*/
public void Initialize(List<string> fileNames)
{
InitializeNatvisServices();
if (fileNames != null && fileNames.Count > 0)
{
if (!Path.IsPathRooted(fileName))
foreach (var fileName in fileNames)
{
string globalVisualizersDirectory = _process.Engine.GetMetric("GlobalVisualizersDirectory") as string;
string globalNatVisPath = null;
if (!string.IsNullOrEmpty(globalVisualizersDirectory) && !string.IsNullOrEmpty(fileName))
{
globalNatVisPath = Path.Combine(globalVisualizersDirectory, fileName);
}

// For local launch, try and load natvis next to the target exe if it exists and if
// the exe is rooted. If the file doesn't exist, and also doesn't exist in the global folder fail.
if (_process.LaunchOptions is LocalLaunchOptions)
if (!string.IsNullOrEmpty(fileName))
{
string exePath = (_process.LaunchOptions as LocalLaunchOptions).ExePath;
if (Path.IsPathRooted(exePath))
if (!Path.IsPathRooted(fileName))
{
string localNatvisPath = Path.Combine(Path.GetDirectoryName(exePath), fileName);
string globalVisualizersDirectory = _process.Engine.GetMetric("GlobalVisualizersDirectory") as string;
string globalNatVisPath = null;
if (!string.IsNullOrEmpty(globalVisualizersDirectory) && !string.IsNullOrEmpty(fileName))
{
globalNatVisPath = Path.Combine(globalVisualizersDirectory, fileName);
}

if (File.Exists(localNatvisPath))
// For local launch, try and load natvis next to the target exe if it exists and if
// the exe is rooted. If the file doesn't exist, and also doesn't exist in the global folder fail.
if (_process.LaunchOptions is LocalLaunchOptions)
{
LoadFile(localNatvisPath);
return;
string exePath = (_process.LaunchOptions as LocalLaunchOptions).ExePath;
if (Path.IsPathRooted(exePath))
{
string localNatvisPath = Path.Combine(Path.GetDirectoryName(exePath), fileName);

if (File.Exists(localNatvisPath))
{
LoadFile(localNatvisPath);
return;
}
else if (globalNatVisPath == null || !File.Exists(globalNatVisPath))
{
// Neither local or global path exists, report an error.
_process.WriteOutput(String.Format(CultureInfo.CurrentCulture, ResourceStrings.FileNotFound, localNatvisPath));
return;
}
}
}
else if (globalNatVisPath == null || !File.Exists(globalNatVisPath))

// Local wasn't supported or the file didn't exist. Try and load from globally registered visualizer directory if local didn't work
// or wasn't supported by the launch options
if (!string.IsNullOrEmpty(globalNatVisPath))
{
// Neither local or global path exists, report an error.
_process.WriteOutput(String.Format(CultureInfo.CurrentCulture, ResourceStrings.FileNotFound, localNatvisPath));
return;
LoadFile(globalNatVisPath);
}
}
else
{
// Full path to the natvis file.. Just try the load
LoadFile(fileName);
}
}

// Local wasn't supported or the file didn't exist. Try and load from globally registered visualizer directory if local didn't work
// or wasn't supported by the launch options
if (!string.IsNullOrEmpty(globalNatVisPath))
{
LoadFile(globalNatVisPath);
}
}
else
{
// Full path to the natvis file.. Just try the load
LoadFile(fileName);
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions test/CppTests/CppTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@
</ItemGroup>

<Target Name="Copy Config and Debuggees" BeforeTargets="DropFiles">
<Copy
SourceFiles="@(ContentFiles)"
DestinationFolder="$(DropDir)\contentFiles\%(RecursiveDir)"
/>
<Copy SourceFiles="@(ContentFiles)" DestinationFolder="$(DropDir)\contentFiles\%(RecursiveDir)" />
</Target>

<ItemGroup>
Expand Down
13 changes: 10 additions & 3 deletions test/CppTests/OpenDebug/CrossPlatCpp/LaunchCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.IO;
using DebuggerTesting.OpenDebug.Commands;
using DebuggerTesting.OpenDebug.CrossPlatCpp;
using DebuggerTesting.Utilities;
using Newtonsoft.Json;

Expand Down Expand Up @@ -34,7 +35,8 @@ public sealed class CppLaunchCommandArgs : LaunchCommandArgs
public string MIMode;

[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string VisualizerFile;
public object VisualizerFile;


[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool ShowDisplayString;
Expand All @@ -50,8 +52,13 @@ public class LaunchCommand : LaunchCommand<CppLaunchCommandArgs>
/// <param name="program">The full path to the program to launch</param>
/// <param name="architecture">The architecture of the program</param>
/// <param name="args">[OPTIONAL] Args to pass to the program</param>
public LaunchCommand(IDebuggerSettings settings, string program, string visualizerFile = null, bool isAttach = false, params string[] args)
public LaunchCommand(IDebuggerSettings settings, string program, object visualizerFile = null, bool isAttach = false, params string[] args)
{
if (!(visualizerFile == null || visualizerFile is string || visualizerFile is List<string>))
{
throw new ArgumentOutOfRangeException(nameof(visualizerFile));
}

this.Timeout = TimeSpan.FromSeconds(15);

this.Args.name = CreateName(settings);
Expand All @@ -75,7 +82,7 @@ public LaunchCommand(IDebuggerSettings settings, string program, string visualiz
this.Args.targetArchitecture = settings.DebuggeeArchitecture.ToArchitectureString();
this.Args.MIMode = settings.MIMode;
this.Args.VisualizerFile = visualizerFile;
this.Args.ShowDisplayString = !string.IsNullOrEmpty(visualizerFile);
this.Args.ShowDisplayString = visualizerFile != null;
}
}

Expand Down
Loading

0 comments on commit 1b020d7

Please sign in to comment.