From a4738a48c1e5311ffcb82a52d2f18ee66aa79513 Mon Sep 17 00:00:00 2001 From: noahfalk Date: Tue, 5 Feb 2019 00:43:32 -0800 Subject: [PATCH] Add new dotnet-sos tool (work originally by mikem, I just split his mega-commit so history would a little more understandable) --- diagnostics.sln | 86 +++++ src/SOS/SOS.InstallHelper/InstallHelper.cs | 307 ++++++++++++++++++ .../SOS.InstallHelper.csproj | 12 + src/SOS/SOS.NETCore/SOS.NETCore.csproj | 61 ---- src/Tools/dotnet-sos/Program.cs | 64 ++++ src/Tools/dotnet-sos/dotnet-sos.csproj | 80 +++++ 6 files changed, 549 insertions(+), 61 deletions(-) create mode 100644 src/SOS/SOS.InstallHelper/InstallHelper.cs create mode 100644 src/SOS/SOS.InstallHelper/SOS.InstallHelper.csproj create mode 100644 src/Tools/dotnet-sos/Program.cs create mode 100644 src/Tools/dotnet-sos/dotnet-sos.csproj diff --git a/diagnostics.sln b/diagnostics.sln index 324aba897..03b8f9473 100644 --- a/diagnostics.sln +++ b/diagnostics.sln @@ -35,6 +35,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debugshim", "src\SOS\debugs EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gcdump", "src\SOS\gcdump\gcdump.vcxproj", "{20EBC3C4-917C-402D-B778-9A6E3742BF5A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SOS.InstallHelper", "src\SOS\SOS.InstallHelper\SOS.InstallHelper.csproj", "{1F012743-941B-4915-8C55-02097894CF3F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-sos", "src\Tools\dotnet-sos\dotnet-sos.csproj", "{41351955-16D5-48D7-AF4C-AF25F5FB2E78}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Checked|Any CPU = Checked|Any CPU @@ -509,6 +513,86 @@ Global {20EBC3C4-917C-402D-B778-9A6E3742BF5A}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 {20EBC3C4-917C-402D-B778-9A6E3742BF5A}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 {20EBC3C4-917C-402D-B778-9A6E3742BF5A}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64 + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|Any CPU.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|ARM.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|ARM.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|ARM64.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|ARM64.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|x64.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|x64.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|x86.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Checked|x86.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|ARM.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|ARM64.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|x64.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|x64.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|x86.ActiveCfg = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Debug|x86.Build.0 = Debug|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|Any CPU.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|ARM.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|ARM.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|ARM64.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|ARM64.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|x64.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|x64.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|x86.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.Release|x86.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|ARM.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|ARM.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|ARM64.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|ARM64.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU + {1F012743-941B-4915-8C55-02097894CF3F}.RelWithDebInfo|x86.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|Any CPU.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|ARM.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|ARM.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|ARM64.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|ARM64.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|x64.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|x64.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|x86.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Checked|x86.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|ARM.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|ARM.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|ARM64.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|x64.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|x64.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|x86.ActiveCfg = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Debug|x86.Build.0 = Debug|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|Any CPU.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|ARM.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|ARM.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|ARM64.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|ARM64.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|x64.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|x64.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|x86.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.Release|x86.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|ARM.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|ARM.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|ARM64.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|ARM64.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU + {41351955-16D5-48D7-AF4C-AF25F5FB2E78}.RelWithDebInfo|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -529,6 +613,8 @@ Global {A9A7C879-C320-3327-BB84-16E1322E17AE} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} {6A94C5FE-8706-3505-834E-DA16242F3864} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} {20EBC3C4-917C-402D-B778-9A6E3742BF5A} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} + {1F012743-941B-4915-8C55-02097894CF3F} = {41638A4C-0DAF-47ED-A774-ECBBAC0315D7} + {41351955-16D5-48D7-AF4C-AF25F5FB2E78} = {B62728C8-1267-4043-B46F-5537BBAEC692} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0} diff --git a/src/SOS/SOS.InstallHelper/InstallHelper.cs b/src/SOS/SOS.InstallHelper/InstallHelper.cs new file mode 100644 index 000000000..4253bb12e --- /dev/null +++ b/src/SOS/SOS.InstallHelper/InstallHelper.cs @@ -0,0 +1,307 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security; + +namespace SOS +{ + /// + /// Functions to install and configure SOS from the package containing this code. + /// + public sealed class InstallHelper + { + /// + /// Well known location to install SOS. Defaults to $HOME/.dotnet/sos on xplat and %USERPROFILE%/.dotnet/sos on Windows. + /// + public string InstallLocation { get; set; } + + /// + /// On Linux/MacOS, the location of the lldb ".lldbinit" file. Defaults to $HOME/.lldbinit. + /// + public string LLDBInitFile { get; set; } + + /// + /// If true, enable the symbol server support when configuring lldb. + /// + public bool EnableSymbolServer { get; set; } = true; + + /// + /// The source path from which SOS is installed. Default is OS/architecture (RID) named directory in the same directory as this assembly. + /// + public string SOSSourcePath { get; set; } + + /// + /// Console output delegate + /// + private Action m_writeLine; + + /// + /// Create an instance of the installer. + /// + /// unknown operating system + /// environment variable not found + public InstallHelper(Action writeLine) + { + m_writeLine = writeLine; + string home = null; + string os = null; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + home = Environment.GetEnvironmentVariable("USERPROFILE"); + if (string.IsNullOrEmpty(home)) { + throw new InvalidOperationException("USERPROFILE environment variable not found"); + } + os = "win"; + } + else + { + home = Environment.GetEnvironmentVariable("HOME"); + if (string.IsNullOrEmpty(home)) { + throw new InvalidOperationException("HOME environment variable not found"); + } + LLDBInitFile = Path.Combine(home, ".lldbinit"); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { + os = "osx"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { + os = "linux"; + } + } + if (os == null) { + throw new PlatformNotSupportedException($"Unsupported operating system {RuntimeInformation.OSDescription}"); + } + InstallLocation = Path.GetFullPath(Path.Combine(home, ".dotnet", "sos")); + + string architecture = RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant(); + string rid = os + "-" + architecture; + SOSSourcePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), rid); + } + + /// + /// Install SOS to well known location (InstallLocation). + /// + /// SOS not found for OS/architecture + /// various + public void Install() + { + WriteLine("Installing SOS to {0} from {1}", InstallLocation, SOSSourcePath); + + if (string.IsNullOrEmpty(SOSSourcePath)) { + throw new ArgumentException("SOS source path not valid"); + } + if (!Directory.Exists(SOSSourcePath)) { + throw new PlatformNotSupportedException($"Operating system or architecture not supported: installing from {SOSSourcePath}"); + } + if (string.IsNullOrEmpty(InstallLocation)) { + throw new ArgumentException($"Installation path {InstallLocation} not valid"); + } + + // Rename any existing installation + string previousInstall = null; + if (Directory.Exists(InstallLocation)) + { + WriteLine("Installing over existing installation..."); + previousInstall = Path.Combine(Path.GetDirectoryName(InstallLocation), Path.GetRandomFileName()); + RetryOperation($"Installation path '{InstallLocation}' not valid", () => Directory.Move(InstallLocation, previousInstall)); + } + + bool installSuccess = false; + try + { + // Create the installation directory + WriteLine("Creating installation directory..."); + RetryOperation($"Installation path '{InstallLocation}' not valid", () => Directory.CreateDirectory(InstallLocation)); + + // Copy SOS files + WriteLine("Copying files..."); + RetryOperation("Problem installing SOS", () => + { + foreach (string file in Directory.EnumerateFiles(SOSSourcePath)) + { + string destinationFile = Path.Combine(InstallLocation, Path.GetFileName(file)); + File.Copy(file, destinationFile, overwrite: true); + } + }); + + // Configure lldb + if (LLDBInitFile != null) { + Configure(); + } + + // If we get here without an exception, success! + installSuccess = true; + } + finally + { + if (previousInstall != null) + { + WriteLine("Cleaning up..."); + if (installSuccess) + { + // Delete the previous installation if the install was successful + RetryOperation(null, () => Directory.Delete(previousInstall, recursive: true)); + } + else + { + // Delete partial installation + RetryOperation(null, () => Directory.Delete(InstallLocation, recursive: true)); + + // Restore previous install + WriteLine("Restoring previous installation..."); + RetryOperation(null, () => Directory.Move(previousInstall, InstallLocation)); + } + } + } + + Debug.Assert(installSuccess); + WriteLine("SOS install succeeded"); + } + + /// + /// Uninstalls and removes the SOS configuration. + /// + /// various + public void Uninstall() + { + WriteLine("Uninstalling SOS from {0}", InstallLocation); + if (!string.IsNullOrEmpty(LLDBInitFile)) + { + Configure(remove: true); + } + if (Directory.Exists(InstallLocation)) + { + RetryOperation("Problem uninstalling SOS", () => Directory.Delete(InstallLocation, recursive: true)); + WriteLine("SOS uninstall succeeded"); + } + else + { + WriteLine("SOS not installed"); + } + } + + const string InitFileStart = "#START - ADDED BY SOS INSTALLER"; + const string InitFileEnd = "#END - ADDED BY SOS INSTALLER"; + + /// + /// Configure lldb to load SOS. + /// + /// if true, remove the configuration from the init file + /// + public void Configure(bool remove = false) + { + if (string.IsNullOrEmpty(LLDBInitFile)) { + throw new ArgumentException("No lldb configuration file path"); + } + bool changed = false; + bool existing = false; + + // Remove the start/end marker from an existing .lldbinit file + var lines = new List(); + if (File.Exists(LLDBInitFile)) + { + existing = true; + bool markerFound = false; + foreach (string line in File.ReadAllLines(LLDBInitFile)) + { + if (line.Contains(InitFileEnd)) { + markerFound = false; + changed = true; + continue; + } + if (!markerFound) { + if (line.Contains(InitFileStart)) { + markerFound = true; + changed = true; + continue; + } + lines.Add(line); + } + } + if (markerFound) { + throw new ArgumentException(".lldbinit file end marker not found"); + } + } + + // If configure (not remove), add the plugin load, etc. configuration between the start/end markers. + if (!remove) + { + lines.Add(InitFileStart); + string plugin = Path.Combine(InstallLocation, "libsosplugin"); + string extension = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? ".dylib" : ".so"; + lines.Add($"plugin load {plugin}{extension}"); + + if (EnableSymbolServer) { + lines.Add(string.Format("setsymbolserver -ms")); + } + lines.Add(InitFileEnd); + changed = true; + } + + // If there is anything to write, write the lldb init file + if (changed) + { + if (remove) { + WriteLine("Reverting {0} file - LLDB will no longer load SOS at startup", LLDBInitFile); + } + else { + WriteLine("{0} {1} file - LLDB will load SOS automatically at startup", existing ? "Updating existing" : "Creating new", LLDBInitFile); + } + RetryOperation($"Problem writing lldb init file {LLDBInitFile}", () => File.WriteAllLines(LLDBInitFile, lines.ToArray())); + } + } + + /// + /// Retries any IO operation failures. + /// + /// text message or null (don't throw exception) + /// callback + /// errorMessage + private void RetryOperation(string errorMessage, Action operation) + { + Exception lastfailure = null; + + for (int retry = 0; retry < 5; retry++) + { + try + { + operation(); + return; + } + catch (Exception ex) when (ex is IOException) + { + // Retry file copy possible recoverable exception + lastfailure = ex; + } + catch (Exception ex) when (ex is ArgumentException || ex is UnauthorizedAccessException || ex is SecurityException) + { + if (errorMessage == null) { + return; + } + throw new ArgumentException($"{errorMessage}: {ex.Message}", ex); + } + } + + if (lastfailure != null) + { + if (errorMessage == null) { + return; + } + throw new ArgumentException($"{errorMessage}: {lastfailure.Message}", lastfailure); + } + } + + private void WriteLine(string format, params object[] args) + { + m_writeLine?.Invoke(string.Format(format, args)); + } + } +} \ No newline at end of file diff --git a/src/SOS/SOS.InstallHelper/SOS.InstallHelper.csproj b/src/SOS/SOS.InstallHelper/SOS.InstallHelper.csproj new file mode 100644 index 000000000..89203e322 --- /dev/null +++ b/src/SOS/SOS.InstallHelper/SOS.InstallHelper.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + SOS.InstallHelper + ;1591;1701 + Diagnostic SOS Install Helper + $(Description) + SOS + true + + diff --git a/src/SOS/SOS.NETCore/SOS.NETCore.csproj b/src/SOS/SOS.NETCore/SOS.NETCore.csproj index a4d723675..a0f80a208 100644 --- a/src/SOS/SOS.NETCore/SOS.NETCore.csproj +++ b/src/SOS/SOS.NETCore/SOS.NETCore.csproj @@ -5,72 +5,11 @@ SOS.NETCore true ;1591;1701 - true - true .NET Core SOS - SOS - $(Description) - SOS - false - $(ArtifactsBinDir)\SOS.NETCore\$(Configuration)\netcoreapp2.0\publish\*.dll - - - <_PackageFiles Include="$(SOSNETCoreBinaries)"> - None - tools/win-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x64.$(Configuration)\sos.dll"> - None - tools/win-x64 - - - <_PackageFiles Include="$(SOSNETCoreBinaries)"> - None - tools/win-x86 - - <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x86.$(Configuration)\sos.dll"> - None - tools/win-x86 - - - <_PackageFiles Include="$(SOSNETCoreBinaries)"> - None - tools/linux-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsosplugin.so"> - None - tools/linux-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsos.so"> - None - tools/linux-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\sosdocsunix.txt"> - None - tools/linux-x64 - - - <_PackageFiles Include="$(SOSNETCoreBinaries)"> - None - tools/osx-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsosplugin.dylib"> - None - tools/osx-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsos.dylib"> - None - tools/osx-x64 - - <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\sosdocsunix.txt"> - None - tools/osx-x64 - - diff --git a/src/Tools/dotnet-sos/Program.cs b/src/Tools/dotnet-sos/Program.cs new file mode 100644 index 000000000..7ab778b20 --- /dev/null +++ b/src/Tools/dotnet-sos/Program.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using McMaster.Extensions.CommandLineUtils; +using SOS; +using System; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Tools.SOS +{ + [Command(Name = "dotnet-sos", Description = "Install and configure SOS")] + internal class Program + { + [Option("--install", Description = "Install and configure SOS.")] + public bool InstallSOS { get; set; } + + [Option("--uninstall", Description = "Uninstall SOS.")] + public bool UninstallSOS { get; set; } + + [Option("--source", Description = "SOS binaries source path.")] + public string SOSSourcePath { get; set; } + + public int OnExecute(IConsole console, CommandLineApplication app) + { + if (InstallSOS || UninstallSOS) + { + var sosInstaller = new InstallHelper((message) => console.WriteLine(message)); + if (SOSSourcePath != null) + { + sosInstaller.SOSSourcePath = SOSSourcePath; + } + try + { + if (UninstallSOS) + { + sosInstaller.Uninstall(); + } + else + { + sosInstaller.Install(); + } + } + catch (Exception ex) when (ex is ArgumentException || ex is PlatformNotSupportedException || ex is InvalidOperationException) + { + console.Error.WriteLine(ex.Message); + return 1; + } + } + return 0; + } + + private static int Main(string[] args) + { + try + { + return CommandLineApplication.Execute(args); + } + catch (OperationCanceledException) + { + return 0; + } + } + } +} diff --git a/src/Tools/dotnet-sos/dotnet-sos.csproj b/src/Tools/dotnet-sos/dotnet-sos.csproj new file mode 100644 index 000000000..00f1271ac --- /dev/null +++ b/src/Tools/dotnet-sos/dotnet-sos.csproj @@ -0,0 +1,80 @@ + + + Exe + netcoreapp2.1 + 2.1.0 + true + true + win-x64;win-x86;osx-x64 + + 1.0.0 + 1.0.0 + dotnet-sos + Microsoft.Diagnostics.Tools.SOS + Diagnostic SOS installer + Diagnostic + $(Description) + + $(OutputPath) + $(ArtifactsBinDir)\SOS.NETCore\$(Configuration)\netcoreapp2.0\publish\*.dll + + + + + + + + + + + + <_PackageFiles Include="$(SOSNETCoreBinaries)"> + None + tools/netcoreapp2.1/any/win-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x64.$(Configuration)\sos.dll"> + None + tools/netcoreapp2.1/any/win-x64 + + <_PackageFiles Include="$(SOSNETCoreBinaries)"> + None + tools/netcoreapp2.1/any/win-x86 + + <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x86.$(Configuration)\sos.dll"> + None + tools/netcoreapp2.1/any/win-x86 + + <_PackageFiles Include="$(SOSNETCoreBinaries)"> + None + tools/netcoreapp2.1/any/linux-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsosplugin.so"> + None + tools/netcoreapp2.1/any/linux-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsos.so"> + None + tools/netcoreapp2.1/any/linux-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\sosdocsunix.txt"> + None + tools/netcoreapp2.1/any/linux-x64 + + <_PackageFiles Include="$(SOSNETCoreBinaries)"> + None + tools/netcoreapp2.1/any/osx-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsosplugin.dylib"> + None + tools/netcoreapp2.1/any/osx-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsos.dylib"> + None + tools/netcoreapp2.1/any/osx-x64 + + <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\sosdocsunix.txt"> + None + tools/netcoreapp2.1/any/osx-x64 + + + -- 2.34.1