From 8e80e0c14b53c7c47a088be19e225198bd85c6b6 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Mon, 10 Jul 2023 12:30:50 -0700 Subject: [PATCH 01/13] Update version to 17.8 (#1409) * Update version to 17.8 --- build/version.settings.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/version.settings.targets b/build/version.settings.targets index 7f0008e95..f606a565b 100644 --- a/build/version.settings.targets +++ b/build/version.settings.targets @@ -3,8 +3,8 @@ 17 - 4 - 2020 + 8 + 2022 14.0.0.0 From 202416e4cd8916b012c796a1bff5e198f03e26cd Mon Sep 17 00:00:00 2001 From: iridinite Date: Sat, 22 Jul 2023 02:19:56 +0200 Subject: [PATCH 02/13] Fix LLDB core dumps loading in separate debug targets (#1396) Co-authored-by: Andrew Wang --- .../Engine.Impl/DebuggedProcess.cs | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs b/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs index 6b9632386..4a0335f06 100755 --- a/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs +++ b/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs @@ -690,17 +690,11 @@ private async Task> GetInitializeCommands() LocalLaunchOptions localLaunchOptions = _launchOptions as LocalLaunchOptions; if (this.IsCoreDump) { - // Add executable information - this.AddExecutablePathCommand(commands); + // Load executable and core dump + this.AddExecutableAndCorePathCommand(commands); - // Important: this must occur after file-exec-and-symbols but before anything else. + // Important: this must occur after executable load but before anything else. this.AddGetTargetArchitectureCommand(commands); - - // Add core dump information (linux/mac does not support quotes around this path but spaces in the path do work) - string coreDump = this.UseUnixPathSeparators ? _launchOptions.CoreDumpPath : this.EnsureProperPathSeparators(_launchOptions.CoreDumpPath, true); - string coreDumpCommand = _launchOptions.DebuggerMIMode == MIMode.Lldb ? String.Concat("target create --core ", coreDump) : String.Concat("-target-select core ", coreDump); - string coreDumpDescription = String.Format(CultureInfo.CurrentCulture, ResourceStrings.LoadingCoreDumpMessage, _launchOptions.CoreDumpPath); - commands.Add(new LaunchCommand(coreDumpCommand, coreDumpDescription, ignoreFailures: false)); } else if (_launchOptions.ProcessId.HasValue) { @@ -918,6 +912,30 @@ private void AddExecutablePathCommand(IList commands) commands.Add(new LaunchCommand("-file-exec-and-symbols " + exe, description, ignoreFailures: false, failureHandler: failureHandler)); } + private void AddExecutableAndCorePathCommand(IList commands) + { + string command; + if (_launchOptions.DebuggerMIMode == MIMode.Lldb) + { + // LLDB requires loading the executable and the core into the same target, using one command. Quotes in the path are supported. + string exePath = this.EnsureProperPathSeparators(_launchOptions.ExePath, true); + string corePath = this.EnsureProperPathSeparators(_launchOptions.CoreDumpPath, true); + command = String.Concat("file ", exePath, " -c ", corePath); + } + else + { + // GDB requires loading the executable and core separately. + // Note: Linux/mac do not support quotes around this path, but spaces in the path do work. + this.AddExecutablePathCommand(commands); + string corePathNoQuotes = this.EnsureProperPathSeparators(_launchOptions.CoreDumpPath, true, true); + command = String.Concat("-target-select core ", corePathNoQuotes); + } + + // Load core dump information + string description = String.Format(CultureInfo.CurrentCulture, ResourceStrings.LoadingCoreDumpMessage, _launchOptions.CoreDumpPath); + commands.Add(new LaunchCommand(command, description, ignoreFailures: false)); + } + private void DetermineAndAddExecutablePathCommand(IList commands, UnixShellPortLaunchOptions launchOptions) { // TODO: connecting to OSX via SSH doesn't work yet. Show error after connection manager dialog gets dismissed. From 3986396d9c31c6ac729c6b52fa79f34d7a253e95 Mon Sep 17 00:00:00 2001 From: Gregg Miskelly Date: Tue, 25 Jul 2023 10:33:41 -0700 Subject: [PATCH 03/13] DAR: Set Encoding to UTF-8 (#1411) DAR failed to set the encoding to UTF-8, leading to corrupt messages if we tried to marshal non-ascii strings. --- test/DebugAdapterRunner/DebugAdapterRunner.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/DebugAdapterRunner/DebugAdapterRunner.cs b/test/DebugAdapterRunner/DebugAdapterRunner.cs index 1e8921452..2d7315f6e 100644 --- a/test/DebugAdapterRunner/DebugAdapterRunner.cs +++ b/test/DebugAdapterRunner/DebugAdapterRunner.cs @@ -56,6 +56,8 @@ public class DebugAdapterRunner private IDictionary _callbackHandlers = new Dictionary(); + private static readonly Encoding s_utf8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); + // Current list of responses received from the debug adapter public List Responses { get; private set; } @@ -155,7 +157,9 @@ private void StartDebugAdapter( startInfo.CreateNoWindow = true; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError = true; + startInfo.RedirectStandardError = true; + startInfo.StandardOutputEncoding = s_utf8NoBOM; + startInfo.StandardInputEncoding = s_utf8NoBOM; if (redirectVSAssert) { From 76427bb68c15edbb5fab0eafd76a03cd66be2e5a Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Mon, 7 Aug 2023 14:37:20 -0700 Subject: [PATCH 04/13] Only use ps 'flags' for macOS (#1412) * Only use ps 'flags' for macOS This PR adds in an operating system check via uname to determine if we should run the PS command with the 'flags' flag. This feature was originally used to determine the architecture of a process for macOS M1 machines that can run as x64 or as arm64. AD7Process only uses the flags field in macOS so this PR updates the command sent to only use it on macOS machines. Other changes: - Updated the setup.csx script to update VS with VS.list instead of VS.Codespaces.list - Updated tests to use the new PSOutputParser - Added a macOS test * Addressing PR issues --- src/SSHDebugPS/AD7/AD7Process.cs | 4 +- src/SSHDebugPS/IConnection.cs | 30 ++++++++++-- src/SSHDebugPS/PSOutputParser.cs | 48 +++++++++++-------- src/SSHDebugPS/PipeConnection.cs | 21 ++++++--- src/SSHDebugPS/SSH/SSHConnection.cs | 15 ++++-- src/SSHDebugTests/PSOutputParserTests.cs | 59 +++++++++++++++++------- tools/Setup.csx | 22 ++++----- tools/VS.CodeSpaces.list | 8 ---- tools/VS.list | 16 +++++++ 9 files changed, 153 insertions(+), 70 deletions(-) delete mode 100644 tools/VS.CodeSpaces.list create mode 100644 tools/VS.list diff --git a/src/SSHDebugPS/AD7/AD7Process.cs b/src/SSHDebugPS/AD7/AD7Process.cs index 09c275867..9675a393b 100644 --- a/src/SSHDebugPS/AD7/AD7Process.cs +++ b/src/SSHDebugPS/AD7/AD7Process.cs @@ -25,7 +25,7 @@ internal class AD7Process : IDebugProcess2, IDebugProcessSecurity2, IDebugProces /// /// Flags are only used in ps command scenarios. It will be set to 0 for others. /// - private readonly uint _flags; + private readonly uint? _flags; /// /// Returns true if _commandLine appears to hold a real file name + args rather than just a description @@ -297,7 +297,7 @@ string IDebugUnixProcess.GetProcessArchitecture() { // For Apple Silicon M1, it is possible that the process we are attaching to is being emulated as x86_64. // The process is emulated if it has process flags has P_TRANSLATED (0x20000). - if (_port.IsOSX() && _systemArch == "arm64") + if (_port.IsOSX() && _systemArch == "arm64" && _flags.HasValue) { if ((_flags & 0x20000) != 0) { diff --git a/src/SSHDebugPS/IConnection.cs b/src/SSHDebugPS/IConnection.cs index 27c4e48ca..36b694d76 100644 --- a/src/SSHDebugPS/IConnection.cs +++ b/src/SSHDebugPS/IConnection.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading; using Microsoft.DebugEngineHost; using Microsoft.SSHDebugPS.Utilities; @@ -104,13 +106,13 @@ public class Process /// /// Only used by the PSOutputParser /// - public uint Flags { get; private set; } + public uint? Flags { get; private set; } public string SystemArch { get; private set; } public string CommandLine { get; private set; } public string UserName { get; private set; } public bool IsSameUser { get; private set; } - public Process(uint id, string arch, uint flags, string userName, string commandLine, bool isSameUser) + public Process(uint id, string arch, uint? flags, string userName, string commandLine, bool isSameUser) { this.Id = id; this.Flags = flags; @@ -121,15 +123,37 @@ public Process(uint id, string arch, uint flags, string userName, string command } } + internal static class OperatingSystemStringConverter + { + internal static PlatformID ConvertToPlatformID(string value) + { + if (!string.IsNullOrEmpty(value)) + { + value = value.ToLowerInvariant(); + if (value.Contains("darwin")) + { + return PlatformID.MacOSX; + } else if (value.Contains("linux")) + { + return PlatformID.Unix; + } + } + Debug.Fail($"Expected a valid platform '{value}' of darwin or linux, but falling back to linux."); + return PlatformID.Unix; + } + } + internal class SystemInformation { public string UserName { get; private set; } public string Architecture { get; private set; } + public PlatformID Platform { get; private set; } - public SystemInformation(string username, string architecture) + public SystemInformation(string username, string architecture, PlatformID platform) { this.UserName = username; this.Architecture = architecture; + Platform = platform; } } } \ No newline at end of file diff --git a/src/SSHDebugPS/PSOutputParser.cs b/src/SSHDebugPS/PSOutputParser.cs index 15fac8a71..d3255f18b 100644 --- a/src/SSHDebugPS/PSOutputParser.cs +++ b/src/SSHDebugPS/PSOutputParser.cs @@ -59,28 +59,27 @@ public string Extract(string line) // Use padding to expand column width. 10 for pid and 32 for userid as that is the max size for each // Tested this format with different distributions of Linux and container distributions. This command (and the alternative without the flags) seems // to be the one that works the best between standard *nix and BusyBox implementations of ps. - private const string PSCommandLineFormat = "ps{0}-o pid=pppppppppp -o flags=ffffffff -o ruser=rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr -o args"; + private const string PSCommandLineFormat = "ps{0}-o pid=pppppppppp{1} -o ruser=rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr -o args"; private SystemInformation _currentSystemInformation; private ColumnDef _pidCol; private ColumnDef _flagsCol; private ColumnDef _ruserCol; private ColumnDef _argsCol; - public static string PSCommandLine = PSCommandLineFormat.FormatInvariantWithArgs(" axww "); - public static string AltPSCommandLine = PSCommandLineFormat.FormatInvariantWithArgs(" "); + // In order to determine the architecture of a process, we need to run the ps command with 'flags'. + // However, certain of distros of Linux do not support flags, so only add this for macOS. + private string PSFlagFormat => _currentSystemInformation.Platform == PlatformID.MacOSX ? " -o flags=ffffffff" : string.Empty; - public static List Parse(string output, SystemInformation systemInformation) - { - return new PSOutputParser().ParseInternal(output, systemInformation); - } + public string PSCommandLine => PSCommandLineFormat.FormatInvariantWithArgs(" axww ", PSFlagFormat); + public string AltPSCommandLine => PSCommandLineFormat.FormatInvariantWithArgs(" ", PSFlagFormat); - private PSOutputParser() + public PSOutputParser(SystemInformation systemInformation) { + _currentSystemInformation = systemInformation; } - private List ParseInternal(string output, SystemInformation systemInformation) + public List Parse(string output) { - _currentSystemInformation = systemInformation; List processList = new List(); using (var reader = new StringReader(output)) @@ -136,14 +135,18 @@ private bool ProcessHeaderLine(/*OPTIONAL*/ string headerLine) if (!SkipNonWhitespace(headerLine, ref index)) return false; - _flagsCol = new ColumnDef(colStart, index); + /// on why this is only executed for macOS. + if (_currentSystemInformation.Platform == PlatformID.MacOSX) + { + _flagsCol = new ColumnDef(colStart, index); - if (!SkipWhitespace(headerLine, ref index)) - return false; + if (!SkipWhitespace(headerLine, ref index)) + return false; - colStart = index; - if (!SkipNonWhitespace(headerLine, ref index)) - return false; + colStart = index; + if (!SkipNonWhitespace(headerLine, ref index)) + return false; + } _ruserCol = new ColumnDef(colStart, index); @@ -170,10 +173,15 @@ private Process SplitPSLine(string line) if (!uint.TryParse(pidText, NumberStyles.None, CultureInfo.InvariantCulture, out pid)) return null; - uint flags; - string flagsText = _flagsCol.Extract(line); - if (!uint.TryParse(flagsText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out flags)) - return null; + uint? flags = null; + /// on why this is only executed for macOS. + if (_currentSystemInformation.Platform == PlatformID.MacOSX) + { + string flagsText = _flagsCol.Extract(line); + if (!uint.TryParse(flagsText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint tempFlags)) + return null; + flags = tempFlags; + } string ruser = _ruserCol.Extract(line); string commandLine = _argsCol.Extract(line); diff --git a/src/SSHDebugPS/PipeConnection.cs b/src/SSHDebugPS/PipeConnection.cs index 94f5ca7ac..ee08786cc 100644 --- a/src/SSHDebugPS/PipeConnection.cs +++ b/src/SSHDebugPS/PipeConnection.cs @@ -98,8 +98,8 @@ public override bool IsLinux() /// SystemInformation containing username and architecture. If it was unable to obtain any of these, the value will be set to string.Empty. public SystemInformation GetSystemInformation() { - string commandOutput; - string errorMessage; + string commandOutput = string.Empty; + string errorMessage = string.Empty; int exitCode; string username = string.Empty; @@ -108,13 +108,19 @@ public SystemInformation GetSystemInformation() username = commandOutput; } + string platform = string.Empty; + if (ExecuteCommand("uname", Timeout.Infinite, commandOutput: out commandOutput, errorMessage: out errorMessage, exitCode: out exitCode)) + { + platform = commandOutput; + } + string architecture = string.Empty; if (ExecuteCommand("uname -m", Timeout.Infinite, commandOutput: out commandOutput, errorMessage: out errorMessage, exitCode: out exitCode)) { architecture = commandOutput; } - return new SystemInformation(username, architecture); + return new SystemInformation(username, architecture, OperatingSystemStringConverter.ConvertToPlatformID(platform)); } public override List ListProcesses() @@ -152,12 +158,15 @@ private bool PSListProcess(SystemInformation systemInformation, out string error errorMessage = string.Empty; string commandOutput; int exitCode; - if (!ExecuteCommand(PSOutputParser.PSCommandLine, Timeout.Infinite, out commandOutput, out errorMessage, out exitCode)) + + PSOutputParser psOutputParser = new PSOutputParser(systemInformation); + + if (!ExecuteCommand(psOutputParser.PSCommandLine, Timeout.Infinite, out commandOutput, out errorMessage, out exitCode)) { // Clear output and errorMessage commandOutput = string.Empty; errorMessage = string.Empty; - if (!ExecuteCommand(PSOutputParser.AltPSCommandLine, Timeout.Infinite, out commandOutput, out errorMessage, out exitCode)) + if (!ExecuteCommand(psOutputParser.AltPSCommandLine, Timeout.Infinite, out commandOutput, out errorMessage, out exitCode)) { if (exitCode == 127) { @@ -174,7 +183,7 @@ private bool PSListProcess(SystemInformation systemInformation, out string error } } - processes = PSOutputParser.Parse(commandOutput, systemInformation); + processes = psOutputParser.Parse(commandOutput); return true; } diff --git a/src/SSHDebugPS/SSH/SSHConnection.cs b/src/SSHDebugPS/SSH/SSHConnection.cs index 56b5f4907..e084b510b 100644 --- a/src/SSHDebugPS/SSH/SSHConnection.cs +++ b/src/SSHDebugPS/SSH/SSHConnection.cs @@ -52,6 +52,13 @@ public override List ListProcesses() username = usernameCommand.Output.TrimEnd('\n', '\r'); // trim line endings because 'id' command ends with a newline } + string operatingSystem = string.Empty; + var operatingSystemCommand = _remoteSystem.Shell.ExecuteCommand("uname", Timeout.InfiniteTimeSpan); + if (operatingSystemCommand.ExitCode == 0) + { + operatingSystem = operatingSystemCommand.Output.TrimEnd('\n', '\r'); // trim line endings because 'uname' command ends with a newline + } + string architecture = string.Empty; var architectureCommand = _remoteSystem.Shell.ExecuteCommand("uname -m", Timeout.InfiniteTimeSpan); if (architectureCommand.ExitCode == 0) @@ -59,15 +66,17 @@ public override List ListProcesses() architecture = architectureCommand.Output.TrimEnd('\n', '\r'); // trim line endings because 'uname -m' command ends with a newline } - SystemInformation systemInformation = new SystemInformation(username, architecture); + SystemInformation systemInformation = new SystemInformation(username, architecture, OperatingSystemStringConverter.ConvertToPlatformID(operatingSystem)); + + PSOutputParser psOutputParser = new PSOutputParser(systemInformation); - var command = _remoteSystem.Shell.ExecuteCommand(PSOutputParser.PSCommandLine, Timeout.InfiniteTimeSpan); + var command = _remoteSystem.Shell.ExecuteCommand(psOutputParser.PSCommandLine, Timeout.InfiniteTimeSpan); if (command.ExitCode != 0) { throw new CommandFailedException(StringResources.Error_PSFailed); } - return PSOutputParser.Parse(command.Output, systemInformation); + return psOutputParser.Parse(command.Output); } /// diff --git a/src/SSHDebugTests/PSOutputParserTests.cs b/src/SSHDebugTests/PSOutputParserTests.cs index bfd74a129..819bcd3cd 100644 --- a/src/SSHDebugTests/PSOutputParserTests.cs +++ b/src/SSHDebugTests/PSOutputParserTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using Microsoft.SSHDebugPS; using System.Collections.Generic; using Xunit; @@ -9,6 +10,29 @@ namespace SSHDebugTests { public class PSOutputParserTests { + [Fact] + public void PSOutputParser_macOS() + { + const string username = "username"; + const string architecture = "x86_64"; + const string input = + "pppppppppp ffffffff rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr ARGS\n" + + "1 4004 root /sbin/launchd\n" + + "50 1004004 root /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd\n" + + "70 1004004 root /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds\n" + + "83 4004 _timed /usr/libexec/timed\n" + + "96 80004104 root /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow console\n" + + "7835 4104 username ps axww -o pid=pppppppppp -o flags=ffffffff -o ruser=rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr -o args\n"; + + PSOutputParser psOutputParser = new PSOutputParser(new SystemInformation(username, architecture, PlatformID.MacOSX)); + List r = psOutputParser.Parse(input); + Assert.Equal(5, r.Count); + // Testing flags here as PID USER ARGS are tested in the other tests. + Assert.Equal(r[0].Flags.Value, (uint)0x4004); + Assert.Equal(r[1].Flags.Value, (uint)0x1004004); + Assert.Equal(r[4].Flags.Value, (uint)0x80004104); + } + [Fact] public void PSOutputParser_Ubuntu14() { @@ -16,15 +40,16 @@ public void PSOutputParser_Ubuntu14() const string architecture = "x86_64"; // example output from ps on a real Ubuntu 14 machine (with many processes removed): const string input = - "pppppppppp ffffffff rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr COMMAND\n" + - " 1 0 root /sbin/init\n" + - " 2 0 root [kthreadd]\n" + - " 720 0 message+ dbus-daemon --system --fork\n" + - " 2389 0 greggm -bash\n" + - " 2580 0 root /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /run/sendsigs.omit.d/network-manager.dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-d08a482b-ff90-4007-9b13-6500eb94b673-eth0.lease -cf /var/lib/NetworkManager/dhclient-eth0.conf eth0\n" + - " 2913 0 greggm ps axww -o pid=pppppppppp -o flags=ffffffff -o ruser=rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr -o args\n"; + "pppppppppp rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr COMMAND\n" + + " 1 root /sbin/init\n" + + " 2 root [kthreadd]\n" + + " 720 message+ dbus-daemon --system --fork\n" + + " 2389 greggm -bash\n" + + " 2580 root /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /run/sendsigs.omit.d/network-manager.dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-d08a482b-ff90-4007-9b13-6500eb94b673-eth0.lease -cf /var/lib/NetworkManager/dhclient-eth0.conf eth0\n" + + " 2913 greggm ps axww -o pid=pppppppppp -o ruser=rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr -o args\n"; - List r = PSOutputParser.Parse(input, new SystemInformation(username, architecture)); + PSOutputParser psOutputParser = new PSOutputParser(new SystemInformation(username, architecture, PlatformID.Unix)); + List r = psOutputParser.Parse(input); Assert.Equal(5, r.Count); uint[] pids = { 1, 2, 720, 2389, 2580 }; @@ -47,10 +72,11 @@ public void PSOutputParser_SmallCol() const string architecture = "x86_64"; // made up output for what could happen if the fields were all just 1 character in size const string input = - "A B C D\n" + - "9 0 r /sbin/init"; + "A B C\n" + + "9 r /sbin/init"; - List r = PSOutputParser.Parse(input, new SystemInformation(username, architecture)); + PSOutputParser psOutputParser = new PSOutputParser(new SystemInformation(username, architecture, PlatformID.Unix)); + List r = psOutputParser.Parse(input); Assert.Single(r); Assert.Equal(9, r[0].Id); Assert.Equal("r", r[0].UserName); @@ -64,12 +90,13 @@ public void PSOutputParser_NoUserName() const string username = ""; const string architecture = ""; const string input = - "pppppppppp ffffffff rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr COMMAND\n" + - " 1 0 root /sbin/init\n" + - " 720 0 dbus-daemon --system --fork\n" + - " 2389 0 greggm -bash\n"; + "pppppppppp rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr COMMAND\n" + + " 1 root /sbin/init\n" + + " 720 dbus-daemon --system --fork\n" + + " 2389 greggm -bash\n"; - List r = PSOutputParser.Parse(input, new SystemInformation(username, architecture)); + PSOutputParser psOutputParser = new PSOutputParser(new SystemInformation(username, architecture, PlatformID.Unix)); + List r = psOutputParser.Parse(input); Assert.Equal(3, r.Count); uint[] pids = { 1, 720, 2389 }; diff --git a/tools/Setup.csx b/tools/Setup.csx index 832030bac..807d4dda9 100644 --- a/tools/Setup.csx +++ b/tools/Setup.csx @@ -195,15 +195,14 @@ class Setup { { vscodeExtensionPath = Path.Join(Environment.GetEnvironmentVariable("HOME"), ".vscode/extensions"); } - IEnumerable extensions = Directory.EnumerateDirectories(vscodeExtensionPath); - - foreach (string extension in extensions) + IEnumerable extensions = Directory.EnumerateDirectories(vscodeExtensionPath).Where(extension => extension.Contains("ms-vscode.cpptools")); + if (extensions.Any()) { - if (extension.Contains("ms-vscode.cpptools")) - { - TargetPath = extension; - break; - } + TargetPath = extensions.First(); + } + else + { + throw new InvalidOperationException("Unable to find an installation of VS Code C++ Extension."); } } } @@ -217,7 +216,7 @@ class Setup { if (Client == Client.VS) { - listFilePath = Path.Join(scriptDirectoryPath, "VS.CodeSpaces.list"); + listFilePath = Path.Join(scriptDirectoryPath, "VS.list"); // Use folder. binDirectoryPath = Path.Join(binDirectoryPath, Configuration.ToString()); } @@ -225,13 +224,12 @@ class Setup { { listFilePath = Path.Join(scriptDirectoryPath, "VSCode.list"); // Use Desktop. folder. - binDirectoryPath = Path.Join(binDirectoryPath, "Desktop." + Configuration.ToString()); + binDirectoryPath = Path.Join(binDirectoryPath, Configuration.ToString()); } if (!Directory.Exists(binDirectoryPath)) { - string configurationToUse = Client == Client.VS ? Configuration.ToString() : "Desktop." + Configuration.ToString(); - throw new InvalidOperationException(string.Format("'{0}' does not exist. Did you build {1}?", binDirectoryPath, configurationToUse)); + throw new InvalidOperationException(string.Format("'{0}' does not exist. Did you build {1}?", binDirectoryPath, Configuration.ToString())); } IList lffList = this.ParseListFiles(listFilePath); diff --git a/tools/VS.CodeSpaces.list b/tools/VS.CodeSpaces.list deleted file mode 100644 index e90f8618f..000000000 --- a/tools/VS.CodeSpaces.list +++ /dev/null @@ -1,8 +0,0 @@ -# filename,source-root,source-dir,install-dir -# Where 'source-root' is either 'src', or 'bin' -Microsoft.MICore.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger -Microsoft.MIDebugEngine.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger -OpenDebugAD7.exe,bin,vscode,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger\vscode -Microsoft.DebugEngineHost.dll,bin,vscode,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger\vscode -Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.dll,bin,vscode,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger\vscode -cppdbg.ad7Engine.json,src,OpenDebugAD7,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger\vscode \ No newline at end of file diff --git a/tools/VS.list b/tools/VS.list new file mode 100644 index 000000000..3106e302b --- /dev/null +++ b/tools/VS.list @@ -0,0 +1,16 @@ +# filename,source-root,source-dir,install-dir +# Where 'source-root' is either 'src', or 'bin' +Microsoft.Android.natvis,src,AndroidDebugLauncher,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.AndroidDebugLauncher.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.AndroidDebugLauncher.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.DebugEngineHost.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.IOSDebugLauncher.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.IOSDebugLauncher.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.JDbg.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MICore.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MICore.XmlSerializers.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MIDebugEngine.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MIDebugEngine.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.SSHDebugPS.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.SSHDebugPS.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +OpenFolderSchema.json,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger \ No newline at end of file From ad8e28a50a206ab2beca7c77e6737f6a305f7c12 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Fri, 18 Aug 2023 15:17:08 -0700 Subject: [PATCH 05/13] Fixing File writing for EngineLogger (#1415) * Fixing File writing for EngineLogger With the Natvis Diagnostics Logger work, the file logger would fail since it would not close the file. This PR also runs 'File.CreateText' in MIDebugCommandDispatcher so errors can be caught earlier and not set an invalid file path. --- src/DebugEngineHost/HostLogger.cs | 2 ++ src/MIDebugEngine/MIDebugCommandDispatcher.cs | 18 ++++++++++++++++++ src/MIDebugPackage/MIDebugPackagePackage.cs | 10 ++++++++++ tools/Setup.csx | 2 +- tools/VS.list | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/DebugEngineHost/HostLogger.cs b/src/DebugEngineHost/HostLogger.cs index 9ce19cf22..22a1934e3 100644 --- a/src/DebugEngineHost/HostLogger.cs +++ b/src/DebugEngineHost/HostLogger.cs @@ -54,7 +54,9 @@ public static ILogChannel GetNatvisLogChannel() public static void Reset() { + s_natvisLogChannel?.Close(); s_natvisLogChannel = null; + s_engineLogChannel?.Close(); s_engineLogChannel = null; } } diff --git a/src/MIDebugEngine/MIDebugCommandDispatcher.cs b/src/MIDebugEngine/MIDebugCommandDispatcher.cs index e07370d38..748d6904a 100644 --- a/src/MIDebugEngine/MIDebugCommandDispatcher.cs +++ b/src/MIDebugEngine/MIDebugCommandDispatcher.cs @@ -4,6 +4,7 @@ using MICore; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -89,6 +90,23 @@ private static void process_DebuggerExitEvent(object sender, EventArgs e) public static void EnableLogging(bool output, string logFile) { + if (!string.IsNullOrEmpty(logFile)) + { + string tempDirectory = Path.GetTempPath(); + if (Path.IsPathRooted(logFile) || (!string.IsNullOrEmpty(tempDirectory) && Directory.Exists(tempDirectory))) + { + string filePath = Path.Combine(tempDirectory, logFile); + + File.CreateText(filePath).Dispose(); // Test to see if we can create a text file in HostLogChannel. This will allow the error to be shown when enabling the setting. + + logFile = filePath; + } + else + { + throw new ArgumentOutOfRangeException(nameof(logFile)); + } + } + Logger.CmdLogInfo.logFile = logFile; if (output) Logger.CmdLogInfo.logToOutput = WriteLogToOutput; diff --git a/src/MIDebugPackage/MIDebugPackagePackage.cs b/src/MIDebugPackage/MIDebugPackagePackage.cs index c28fe9162..be94cc4cd 100644 --- a/src/MIDebugPackage/MIDebugPackagePackage.cs +++ b/src/MIDebugPackage/MIDebugPackagePackage.cs @@ -403,6 +403,16 @@ private void LaunchDebugTarget(string filePath, string options) private void EnableLogging(bool sendToOutputWindow, string logFile) { ThreadHelper.ThrowIfNotOnUIThread(); + + IVsDebugger debugger = (IVsDebugger)GetService(typeof(IVsDebugger)); + DBGMODE[] mode = new DBGMODE[] { DBGMODE.DBGMODE_Design }; + int hr = debugger.GetMode(mode); + + if (hr == VSConstants.S_OK && mode[0] != DBGMODE.DBGMODE_Design) + { + throw new ArgumentException("Unable to update MIDebugLog while debugging."); + } + try { MIDebugCommandDispatcher.EnableLogging(sendToOutputWindow, logFile); diff --git a/tools/Setup.csx b/tools/Setup.csx index 807d4dda9..9931534ce 100644 --- a/tools/Setup.csx +++ b/tools/Setup.csx @@ -218,7 +218,7 @@ class Setup { { listFilePath = Path.Join(scriptDirectoryPath, "VS.list"); // Use folder. - binDirectoryPath = Path.Join(binDirectoryPath, Configuration.ToString()); + binDirectoryPath = Path.Join(binDirectoryPath, "Lab." + Configuration.ToString()); } else if (Client == Client.VSCode) { diff --git a/tools/VS.list b/tools/VS.list index 3106e302b..dc274f437 100644 --- a/tools/VS.list +++ b/tools/VS.list @@ -11,6 +11,8 @@ Microsoft.MICore.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger Microsoft.MICore.XmlSerializers.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger Microsoft.MIDebugEngine.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger Microsoft.MIDebugEngine.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MIDebugPackage.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger +Microsoft.MIDebugPackage.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger Microsoft.SSHDebugPS.dll,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger Microsoft.SSHDebugPS.pkgdef,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger OpenFolderSchema.json,bin,,\Common7\IDE\CommonExtensions\Microsoft\MDD\Debugger \ No newline at end of file From e31522844d47e9525225ce568d49367e8ff080a8 Mon Sep 17 00:00:00 2001 From: Patryk Schneider Date: Tue, 7 Mar 2023 16:33:06 +0100 Subject: [PATCH 06/13] MIEngine: Fix Disassembly fail on GPU if startAddress is offset --- src/MIDebugEngine/Engine.Impl/Disassembly.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/MIDebugEngine/Engine.Impl/Disassembly.cs b/src/MIDebugEngine/Engine.Impl/Disassembly.cs index f08b928ec..a52c42c5a 100644 --- a/src/MIDebugEngine/Engine.Impl/Disassembly.cs +++ b/src/MIDebugEngine/Engine.Impl/Disassembly.cs @@ -308,8 +308,21 @@ private void DeleteRangeFromCache(DisassemblyBlock block) // this is inefficient so we try and grab everything in one gulp internal static async Task Disassemble(DebuggedProcess process, ulong startAddr, ulong endAddr) { - string cmd = "-data-disassemble -s " + EngineUtils.AsAddr(startAddr, process.Is64BitArch) + " -e " + EngineUtils.AsAddr(endAddr, process.Is64BitArch) + " -- 2"; - Results results = await process.CmdAsync(cmd, ResultClass.None); + string cmd; + string startAddrStr; + string endAddrStr; + int i = 0; + Results results; + do + { + startAddrStr = EngineUtils.AsAddr(startAddr, process.Is64BitArch); + endAddrStr = EngineUtils.AsAddr(endAddr, process.Is64BitArch); + cmd = "-data-disassemble -s " + startAddrStr + " -e " + endAddrStr + " -- 2"; + results = await process.CmdAsync(cmd, ResultClass.None); + --startAddr; + ++i; + } while (results.ResultClass != ResultClass.done && i < process.MaxInstructionSize); + if (results.ResultClass != ResultClass.done) { return null; From 7a02ace2b740556b04e90e4e87d2e19c7add4c2e Mon Sep 17 00:00:00 2001 From: paulmaybee Date: Wed, 18 Oct 2023 09:36:02 -0700 Subject: [PATCH 07/13] Get all startup msgs into log file (#1419) --- src/MIDebugEngine/AD7.Impl/AD7Engine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MIDebugEngine/AD7.Impl/AD7Engine.cs b/src/MIDebugEngine/AD7.Impl/AD7Engine.cs index ad050bd4f..b9e60a869 100755 --- a/src/MIDebugEngine/AD7.Impl/AD7Engine.cs +++ b/src/MIDebugEngine/AD7.Impl/AD7Engine.cs @@ -189,7 +189,7 @@ public int Attach(IDebugProgram2[] portProgramArray, IDebugProgramNode2[] progra { Debug.Assert(_ad7ProgramId == Guid.Empty); - Logger.LoadMIDebugLogger(); + Logger.EnsureInitialized(); if (celtPrograms != 1) { @@ -539,7 +539,7 @@ int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, stri Debug.Assert(_ad7ProgramId == Guid.Empty); // Check if the logger was enabled late. - Logger.LoadMIDebugLogger(); + Logger.EnsureInitialized(); process = null; From 56e34e4bae7e279baf37d3f77849a57c8e2ba3d3 Mon Sep 17 00:00:00 2001 From: paulmaybee Date: Mon, 23 Oct 2023 13:12:24 -0700 Subject: [PATCH 08/13] mark logger not initialized on close (#1422) Co-authored-by: Andrew Wang --- src/MICore/Logger.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MICore/Logger.cs b/src/MICore/Logger.cs index 86e2db72f..671366294 100644 --- a/src/MICore/Logger.cs +++ b/src/MICore/Logger.cs @@ -97,6 +97,7 @@ public static void Reset() { HostLogger.Reset(); s_isEnabled = false; + s_isInitialized = false; } } From 10b57604ba020857cec02fa5f7f7f12a8b802735 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Tue, 28 Nov 2023 13:10:23 -0800 Subject: [PATCH 09/13] Address .NET 8 SDK Build issues (#1425) This PR addresses issues building MIEngine with .NET 8 SDK. See https://github.com/dotnet/sdk/issues/34438 --- src/SSHDebugPS/SSHDebugPS.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SSHDebugPS/SSHDebugPS.csproj b/src/SSHDebugPS/SSHDebugPS.csproj index bcbe89061..677a34d63 100644 --- a/src/SSHDebugPS/SSHDebugPS.csproj +++ b/src/SSHDebugPS/SSHDebugPS.csproj @@ -13,7 +13,7 @@ net472 true true - false + true From 9f35772d171e37a10322309bf0477512941531f5 Mon Sep 17 00:00:00 2001 From: Rakesh Ganesh Date: Tue, 28 Nov 2023 22:35:20 +0100 Subject: [PATCH 10/13] MIEngine: Array evaluation and address check (#1427) * MIEngine: Address is not an AD7MemoryAddress obj Handle condition where the address is not an AD7MemoryAddress object. On running multiple debug engines, it appears this gets called with a different object type. Signed-off-by: intel-rganesh rakesh.ganesh@intel.com * MIEngine: Allow direct array evaluation Allow direct array eval in memory window. Signed-off-by: intel-rganesh rakesh.ganesh@intel.com * MIEngine: Address review comments Address review comments for array evaluation and address check: 1> Use the correct constant in AD7Disassembly when pCodeContext is not AD7MemoryAddress. 2> Avoid creating new AD7Property to fetch variable information value. Signed-off-by: intel-rganesh rakesh.ganesh@intel.com --------- Signed-off-by: intel-rganesh rakesh.ganesh@intel.com Co-authored-by: Andrew Wang --- src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs | 10 +++++-- src/MIDebugEngine/AD7.Impl/AD7Property.cs | 30 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs diff --git a/src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs b/src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs old mode 100644 new mode 100755 index b699a49df..2594376b6 --- a/src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs +++ b/src/MIDebugEngine/AD7.Impl/AD7Disassembly.cs @@ -34,8 +34,14 @@ public int GetCodeContext(ulong uCodeLocationId, out IDebugCodeContext2 ppCodeCo public int GetCodeLocationId(IDebugCodeContext2 pCodeContext, out ulong puCodeLocationId) { AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress; - puCodeLocationId = addr.Address; - return Constants.S_OK; + if (addr != null) + { + puCodeLocationId = addr.Address; + return Constants.S_OK; + } + + puCodeLocationId = 0; + return Constants.E_FAIL; } public int GetCurrentLocation(out ulong puCodeLocationId) diff --git a/src/MIDebugEngine/AD7.Impl/AD7Property.cs b/src/MIDebugEngine/AD7.Impl/AD7Property.cs index 2601d2c48..54ee427bd 100644 --- a/src/MIDebugEngine/AD7.Impl/AD7Property.cs +++ b/src/MIDebugEngine/AD7.Impl/AD7Property.cs @@ -229,11 +229,37 @@ public int GetMemoryContext(out IDebugMemoryContext2 ppMemory) { return AD7_HRESULT.S_GETMEMORYCONTEXT_NO_MEMORY_CONTEXT; } - v = v.Trim(); + + if ((v[0] == '[') && (v[v.Length-1] == ']')) + { + // this is an array evaluation result from GDB, which does not contain an address + // VS on the other hand supports direct array evaluations without address operator + // therefore we need to re-evaluate with an address operator + // + VariableInformation viArray = new VariableInformation("&(" + _variableInformation.FullName() + ")", (VariableInformation)_variableInformation); + viArray.SyncEval(); + if (viArray.Error) + { + return AD7_HRESULT.S_GETMEMORYCONTEXT_NO_MEMORY_CONTEXT; + } + v = viArray.Value; + v.Trim(); + if (v.Length == 0) + { + return AD7_HRESULT.S_GETMEMORYCONTEXT_NO_MEMORY_CONTEXT; + } + } + if (v[0] == '{') { + var index = v.IndexOf('}'); + if (index == -1) + { + // syntax error! + return AD7_HRESULT.S_GETMEMORYCONTEXT_NO_MEMORY_CONTEXT; + } // strip type name and trailing spaces - v = v.Substring(v.IndexOf('}') + 1); + v = v.Substring(index+1); v = v.Trim(); } int i = v.IndexOf(' '); From 97b44d777a6417cd4d7b49f3c4aa1585ee916976 Mon Sep 17 00:00:00 2001 From: Anton Burticica Date: Mon, 4 Dec 2023 19:56:27 +0200 Subject: [PATCH 11/13] Reverse sort sourceMap (#1428) Do reverse sort of the `sourceMap`. In my `launch.json` configuration I have the following `sourceFileMap`: ``` "sourceFileMap": { "/usr/src/debug/my-project/git-r0/build/src/../../git": "${workspaceFolder}", "/usr/src/debug": { "editorPath": "${config:YOCTO_ARCH}", "useForBreakpoints": false } }, ``` The YOCTO_ARCH set in `settings.json` to: ``` "terminal.integrated.env.linux": { "YOCTO_ARCH": "/home/mouse/linux-bsp/linux-devel-build/build/work/cortexa7t2hf-neon-vfpv4_linux-linux-gnueabi" }, ``` This PR addresses an issue encountered while debugging a binary that's running on a remote system and built using Yocto. Currently, when debugging, the source files are being referenced from the Yocto build tree instead of the local workspace. This issue prevents setting breakpoints effectively in the local workspace source files. To resolve this, the change involves modifying the way source mappings are processed. Specifically, it proposes sorting the mappings in reverse order, starting with the longer, more specific paths and moving towards the more general ones. By doing this, the debugger will first consider the project-specific paths defined in `sourceFileMap`. If it doesn't find a match there, it will then fall back to the more general paths. This reverse sorting ensures that the local workspace sources are prioritized over the Yocto build tree sources, allowing for effective breakpoint setting and debugging in the local workspace. --- src/MICore/LaunchOptions.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/MICore/LaunchOptions.cs b/src/MICore/LaunchOptions.cs index 7c102711f..95f1ee049 100644 --- a/src/MICore/LaunchOptions.cs +++ b/src/MICore/LaunchOptions.cs @@ -370,7 +370,7 @@ public static ReadOnlyCollection CreateCollection(Xml.LaunchOpti public static ReadOnlyCollection CreateCollection(Dictionary source) { - IList sourceMaps = new List(source.Keys.Count); + var sourceMaps = new List(source.Keys.Count); foreach (var item in source) { @@ -416,6 +416,11 @@ public static ReadOnlyCollection CreateCollection(Dictionary string.CompareOrdinal(y.CompileTimePath, x.CompileTimePath)); + return new ReadOnlyCollection(sourceMaps); } } From 2a0f9efa65869f9ae64f1f5782c50998d31baa22 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:02:19 -0800 Subject: [PATCH 12/13] Fix missing s32 format specifier support (#1431) Fix s32 format specifier support --- src/MIDebugEngine/Engine.Impl/Variables.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MIDebugEngine/Engine.Impl/Variables.cs b/src/MIDebugEngine/Engine.Impl/Variables.cs index 32e6b78b7..8c297998f 100644 --- a/src/MIDebugEngine/Engine.Impl/Variables.cs +++ b/src/MIDebugEngine/Engine.Impl/Variables.cs @@ -425,6 +425,9 @@ private string ProcessFormatSpecifiers(string exp, out string formatSpecifier) case "su": case "sub": return "(const char16_t*)(" + exp.Substring(0, lastComma) + ")"; + case "s32": + case "s32b": + return "(const char32_t*)(" + exp.Substring(0, lastComma) + ")"; case "c": return "(char)(" + exp.Substring(0, lastComma) + ")"; // just remove and ignore these From 40175199ebe98db558c5fc609ffb85fec51bc9ce Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Tue, 2 Jan 2024 14:48:16 -0800 Subject: [PATCH 13/13] Theme Docker Container Selector Dialog (#1430) * Theme Docker Container Selector Dialog This PR updates the Docker Container Selector Dialog in Visual Studio to be themed. The following changes were done: - Updates VS packages since some of the newer theming was in newer packages. - Newer packages had new attributes that needed to be handled with MakePIAPortableTool. - Converted ListBox to ListView for ContainerPickerDialog and modified associated automation peers * Address PR issues * Revert to 17.5.33428.366 * Remove Maximize Functionality * Address title bar issues --- build/package_versions.settings.targets | 26 +- src/DebugEngineHost/DebugEngineHost.csproj | 2 - src/MIDebugPackage/MIDebugPackage.csproj | 2 - src/MakePIAPortable/MakePIAPortable.csproj | 14 +- src/SSHDebugPS/SSHDebugPS.csproj | 2 - .../UI/ContainerPickerDialogWindow.xaml | 350 ++++++++++-------- .../UI/ContainerPickerDialogWindow.xaml.cs | 27 +- .../ContainerListBoxItemAutomationPeer.cs | 4 +- ....cs => ContainerListViewAutomationPeer.cs} | 6 +- .../UI/Controls/ContainerListBox.cs | 4 +- .../Converters/BoolToVisibilityConverter.cs | 5 +- .../MakePIAPortableTool.cs | 5 +- 12 files changed, 247 insertions(+), 200 deletions(-) rename src/SSHDebugPS/UI/Controls/Automation/{ContainerListBoxAutomationPeer.cs => ContainerListViewAutomationPeer.cs} (61%) diff --git a/build/package_versions.settings.targets b/build/package_versions.settings.targets index c1eee41bb..470194d01 100644 --- a/build/package_versions.settings.targets +++ b/build/package_versions.settings.targets @@ -1,8 +1,8 @@ 1.0.1 - 17.0.0-previews-1-31410-258 - 13.0.1 + 17.8.37221 + 13.0.3 17.2.60629.1 @@ -19,20 +19,20 @@ 17.0.28-g439d20ddd3 17.0.1051901-preview - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.0-previews-1-31410-258 - 17.0.17-alpha - 17.0.0-previews-1-31410-258 + 17.5.33428.388 + 17.5.33428.366 + 17.5.33428.366 + 17.5.33428.366 + 17.5.33428.366 + 17.5.33428.366 + 17.8.37221 + 17.8.37221 + 17.8.14 + 17.8.37221 15.0.26932 15.0.392 15.0.392 - 17.0.0-previews-1-31410-258 + 17.8.37221 17.3.2093 4.3.0 diff --git a/src/DebugEngineHost/DebugEngineHost.csproj b/src/DebugEngineHost/DebugEngineHost.csproj index 5a09a365d..03bd58c69 100755 --- a/src/DebugEngineHost/DebugEngineHost.csproj +++ b/src/DebugEngineHost/DebugEngineHost.csproj @@ -88,8 +88,6 @@ compile all - - diff --git a/src/MIDebugPackage/MIDebugPackage.csproj b/src/MIDebugPackage/MIDebugPackage.csproj index 67e436c68..fe7a3a4ad 100755 --- a/src/MIDebugPackage/MIDebugPackage.csproj +++ b/src/MIDebugPackage/MIDebugPackage.csproj @@ -38,8 +38,6 @@ - - compile all diff --git a/src/MakePIAPortable/MakePIAPortable.csproj b/src/MakePIAPortable/MakePIAPortable.csproj index 16fd00340..235f6baf0 100644 --- a/src/MakePIAPortable/MakePIAPortable.csproj +++ b/src/MakePIAPortable/MakePIAPortable.csproj @@ -41,13 +41,13 @@ - - - - - - - + + + + + + + diff --git a/src/SSHDebugPS/SSHDebugPS.csproj b/src/SSHDebugPS/SSHDebugPS.csproj index 677a34d63..f270e64e6 100644 --- a/src/SSHDebugPS/SSHDebugPS.csproj +++ b/src/SSHDebugPS/SSHDebugPS.csproj @@ -27,8 +27,6 @@ all - - diff --git a/src/SSHDebugPS/UI/ContainerPickerDialogWindow.xaml b/src/SSHDebugPS/UI/ContainerPickerDialogWindow.xaml index c765009f6..cfdc1e8d6 100644 --- a/src/SSHDebugPS/UI/ContainerPickerDialogWindow.xaml +++ b/src/SSHDebugPS/UI/ContainerPickerDialogWindow.xaml @@ -6,7 +6,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:platformui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0" - xmlns:vsui="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell" + xmlns:vsui="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0" xmlns:vsimaging="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.Imaging" xmlns:catalog="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.ImageCatalog" xmlns:local="clr-namespace:Microsoft.SSHDebugPS" @@ -18,22 +18,116 @@ Height="600" ShowInTaskbar="False" Name="ContainerPickerDialog" + Background="{DynamicResource {x:Static platformui:ThemedDialogColors.WindowPanelBrushKey}}" + Foreground="{DynamicResource {x:Static platformui:ThemedDialogColors.WindowPanelTextBrushKey}}" FontFamily="{DynamicResource VsFont.EnvironmentFontFamily}" FontSize="{DynamicResource VsFont.EnvironmentFontSize}" Title="{x:Static local:UIResources.DialogTitle}" WindowStartupLocation="CenterOwner"> + + + + + + + + + + + + @@ -103,7 +198,7 @@ Value="Transparent" /> - - - @@ -278,6 +276,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /// Must be IContainerViewModel - public class ContainerListBoxItemAutomationPeer : + public class ContainerListViewItemAutomationPeer : ListBoxItemAutomationPeer, IExpandCollapseProvider where T : IContainerViewModel { - public ContainerListBoxItemAutomationPeer(object item, ContainerListBoxAutomationPeer ownerAutomationPeer) + public ContainerListViewItemAutomationPeer(object item, ContainerListViewAutomationPeer ownerAutomationPeer) : base(item, ownerAutomationPeer) { } diff --git a/src/SSHDebugPS/UI/Controls/Automation/ContainerListBoxAutomationPeer.cs b/src/SSHDebugPS/UI/Controls/Automation/ContainerListViewAutomationPeer.cs similarity index 61% rename from src/SSHDebugPS/UI/Controls/Automation/ContainerListBoxAutomationPeer.cs rename to src/SSHDebugPS/UI/Controls/Automation/ContainerListViewAutomationPeer.cs index 8c204eab8..9efcf9650 100644 --- a/src/SSHDebugPS/UI/Controls/Automation/ContainerListBoxAutomationPeer.cs +++ b/src/SSHDebugPS/UI/Controls/Automation/ContainerListViewAutomationPeer.cs @@ -5,15 +5,15 @@ namespace Microsoft.SSHDebugPS.UI { - public class ContainerListBoxAutomationPeer : ListBoxAutomationPeer + public class ContainerListViewAutomationPeer : ListViewAutomationPeer { - public ContainerListBoxAutomationPeer(ContainerListBox owner) + public ContainerListViewAutomationPeer(ContainerListView owner) : base(owner) { } protected override ItemAutomationPeer CreateItemAutomationPeer(object item) { - return new ContainerListBoxItemAutomationPeer(item, this); + return new ContainerListViewItemAutomationPeer(item, this); } } } diff --git a/src/SSHDebugPS/UI/Controls/ContainerListBox.cs b/src/SSHDebugPS/UI/Controls/ContainerListBox.cs index 40d84cd6c..30e8d5c5b 100644 --- a/src/SSHDebugPS/UI/Controls/ContainerListBox.cs +++ b/src/SSHDebugPS/UI/Controls/ContainerListBox.cs @@ -6,11 +6,11 @@ namespace Microsoft.SSHDebugPS.UI { - public class ContainerListBox : ListBox + public class ContainerListView : ListView { protected override AutomationPeer OnCreateAutomationPeer() { - return new ContainerListBoxAutomationPeer(this); + return new ContainerListViewAutomationPeer(this); } } } diff --git a/src/SSHDebugPS/UI/Converters/BoolToVisibilityConverter.cs b/src/SSHDebugPS/UI/Converters/BoolToVisibilityConverter.cs index b2a983bb3..81e7bf42a 100644 --- a/src/SSHDebugPS/UI/Converters/BoolToVisibilityConverter.cs +++ b/src/SSHDebugPS/UI/Converters/BoolToVisibilityConverter.cs @@ -9,12 +9,13 @@ namespace Microsoft.SSHDebugPS.Docker { internal class BoolToVisibilityConverter : IValueConverter { + public bool Negative { get; set; } + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (targetType == typeof(Visibility)) { - // Could have a parameter - if (parameter != null) + if (Negative) { // Only allowed param is flip return (bool)value ? Visibility.Collapsed : Visibility.Visible; diff --git a/src/tools/MakePIAPortableTool/MakePIAPortableTool.cs b/src/tools/MakePIAPortableTool/MakePIAPortableTool.cs index a4740d4f7..7019f918e 100644 --- a/src/tools/MakePIAPortableTool/MakePIAPortableTool.cs +++ b/src/tools/MakePIAPortableTool/MakePIAPortableTool.cs @@ -67,6 +67,8 @@ class Program { "System.DateTime", System_Runtime }, { "System.ObsoleteAttribute", System_Runtime }, { "System.Attribute", System_Runtime }, + { "System.AttributeUsageAttribute", System_Runtime }, + { "System.AttributeTargets", System_Runtime }, // System.Runtime.InteropServices { "System.Runtime.InteropServices.ClassInterfaceAttribute", System_Runtime_InteropServices }, @@ -302,7 +304,8 @@ private static bool IsIgnoredCustomAttributeLine(string line) line.Contains(".custom instance void [mscorlib]System.Runtime.InteropServices.TypeLibFuncAttribute::.ctor(") || line.Contains(".custom instance void [mscorlib]System.Runtime.InteropServices.TypeLibFuncAttribute::.ctor(") || line.Contains(".custom instance void [mscorlib]System.Resources.SatelliteContractVersionAttribute::.ctor(") || - line.Contains(".custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor("); + line.Contains(".custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(") || + line.Contains(".custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor("); } private static void SkipClass(InputFile inputFile)