(work originally by mikem, I just split his mega-commit so history would a little more understandable)
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
{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
{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}
--- /dev/null
+// 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
+{
+ /// <summary>
+ /// Functions to install and configure SOS from the package containing this code.
+ /// </summary>
+ public sealed class InstallHelper
+ {
+ /// <summary>
+ /// Well known location to install SOS. Defaults to $HOME/.dotnet/sos on xplat and %USERPROFILE%/.dotnet/sos on Windows.
+ /// </summary>
+ public string InstallLocation { get; set; }
+
+ /// <summary>
+ /// On Linux/MacOS, the location of the lldb ".lldbinit" file. Defaults to $HOME/.lldbinit.
+ /// </summary>
+ public string LLDBInitFile { get; set; }
+
+ /// <summary>
+ /// If true, enable the symbol server support when configuring lldb.
+ /// </summary>
+ public bool EnableSymbolServer { get; set; } = true;
+
+ /// <summary>
+ /// The source path from which SOS is installed. Default is OS/architecture (RID) named directory in the same directory as this assembly.
+ /// </summary>
+ public string SOSSourcePath { get; set; }
+
+ /// <summary>
+ /// Console output delegate
+ /// </summary>
+ private Action<string> m_writeLine;
+
+ /// <summary>
+ /// Create an instance of the installer.
+ /// </summary>
+ /// <exception cref="PlatformNotSupportedException">unknown operating system</exception>
+ /// <exception cref="InvalidOperationException">environment variable not found</exception>
+ public InstallHelper(Action<string> 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);
+ }
+
+ /// <summary>
+ /// Install SOS to well known location (InstallLocation).
+ /// </summary>
+ /// <exception cref="PlatformNotSupportedException">SOS not found for OS/architecture</exception>
+ /// <exception cref="ArgumentException">various</exception>
+ 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");
+ }
+
+ /// <summary>
+ /// Uninstalls and removes the SOS configuration.
+ /// </summary>
+ /// <exception cref="ArgumentException">various</exception>
+ 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";
+
+ /// <summary>
+ /// Configure lldb to load SOS.
+ /// </summary>
+ /// <param name="remove">if true, remove the configuration from the init file</param>
+ /// <exception cref="ArgumentException"></exception>
+ 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<string>();
+ 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()));
+ }
+ }
+
+ /// <summary>
+ /// Retries any IO operation failures.
+ /// </summary>
+ /// <param name="errorMessage">text message or null (don't throw exception)</param>
+ /// <param name="operation">callback</param>
+ /// <exception cref="ArgumentException">errorMessage</exception>
+ 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
--- /dev/null
+<!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <AssemblyName>SOS.InstallHelper</AssemblyName>
+ <NoWarn>;1591;1701</NoWarn>
+ <Description>Diagnostic SOS Install Helper</Description>
+ <PackageReleaseNotes>$(Description)</PackageReleaseNotes>
+ <PackageTags>SOS</PackageTags>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+</Project>
<AssemblyName>SOS.NETCore</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>;1591;1701</NoWarn>
- <IsPackable>true</IsPackable>
- <IsPublishable>true</IsPublishable>
<Description>.NET Core SOS</Description>
- <PackageId>SOS</PackageId>
- <PackageReleaseNotes>$(Description)</PackageReleaseNotes>
- <PackageTags>SOS</PackageTags>
- <IncludeBuildOutput>false</IncludeBuildOutput>
- <SOSNETCoreBinaries>$(ArtifactsBinDir)\SOS.NETCore\$(Configuration)\netcoreapp2.0\publish\*.dll</SOSNETCoreBinaries>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="Microsoft.SymbolStore" Version="$(MicrosoftSymbolStoreVersion)" />
</ItemGroup>
-
- <ItemGroup>
- <_PackageFiles Include="$(SOSNETCoreBinaries)">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/win-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x64.$(Configuration)\sos.dll">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/win-x64</PackagePath>
- </_PackageFiles>
-
- <_PackageFiles Include="$(SOSNETCoreBinaries)">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/win-x86</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x86.$(Configuration)\sos.dll">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/win-x86</PackagePath>
- </_PackageFiles>
-
- <_PackageFiles Include="$(SOSNETCoreBinaries)">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/linux-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsosplugin.so">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/linux-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsos.so">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/linux-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\sosdocsunix.txt">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/linux-x64</PackagePath>
- </_PackageFiles>
-
- <_PackageFiles Include="$(SOSNETCoreBinaries)">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/osx-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsosplugin.dylib">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/osx-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsos.dylib">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/osx-x64</PackagePath>
- </_PackageFiles>
- <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\sosdocsunix.txt">
- <BuildAction>None</BuildAction>
- <PackagePath>tools/osx-x64</PackagePath>
- </_PackageFiles>
- </ItemGroup>
</Project>
--- /dev/null
+// 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<Program>(args);
+ }
+ catch (OperationCanceledException)
+ {
+ return 0;
+ }
+ }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
+ <RuntimeFrameworkVersion>2.1.0</RuntimeFrameworkVersion>
+ <IsPackable>true</IsPackable>
+ <PackAsTool>true</PackAsTool>
+ <PackAsToolShimRuntimeIdentifiers>win-x64;win-x86;osx-x64</PackAsToolShimRuntimeIdentifiers>
+ <!-- The package version needs to be hard coded as a stable version so "dotnet tool install -g dotnet-sos" works -->
+ <Version>1.0.0</Version>
+ <PackageVersion>1.0.0</PackageVersion>
+ <ToolCommandName>dotnet-sos</ToolCommandName>
+ <RootNamespace>Microsoft.Diagnostics.Tools.SOS</RootNamespace>
+ <Description>Diagnostic SOS installer</Description>
+ <PackageTags>Diagnostic</PackageTags>
+ <PackageReleaseNotes>$(Description)</PackageReleaseNotes>
+ <!-- Need to put the shims here to sign -->
+ <PackagedShimOutputRootDirectory>$(OutputPath)</PackagedShimOutputRootDirectory>
+ <SOSNETCoreBinaries>$(ArtifactsBinDir)\SOS.NETCore\$(Configuration)\netcoreapp2.0\publish\*.dll</SOSNETCoreBinaries>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.2.5" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\SOS\SOS.InstallHelper\SOS.InstallHelper.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <_PackageFiles Include="$(SOSNETCoreBinaries)">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/win-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x64.$(Configuration)\sos.dll">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/win-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(SOSNETCoreBinaries)">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/win-x86</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\Windows_NT.x86.$(Configuration)\sos.dll">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/win-x86</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(SOSNETCoreBinaries)">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/linux-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsosplugin.so">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/linux-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\libsos.so">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/linux-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\Linux.x64.$(Configuration)\sosdocsunix.txt">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/linux-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(SOSNETCoreBinaries)">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/osx-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsosplugin.dylib">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/osx-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\libsos.dylib">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/osx-x64</PackagePath>
+ </_PackageFiles>
+ <_PackageFiles Include="$(ArtifactsBinDir)\OSX.x64.$(Configuration)\sosdocsunix.txt">
+ <BuildAction>None</BuildAction>
+ <PackagePath>tools/netcoreapp2.1/any/osx-x64</PackagePath>
+ </_PackageFiles>
+ </ItemGroup>
+</Project>