Fix some misc SOS issues (#966)
authorMike McLaughlin <mikem@microsoft.com>
Mon, 30 Mar 2020 16:49:27 +0000 (09:49 -0700)
committerGitHub <noreply@github.com>
Mon, 30 Mar 2020 16:49:27 +0000 (09:49 -0700)
* Display some more MT info

* Issue https://github.com/dotnet/diagnostics/issues/816

* Issue https://github.com/dotnet/diagnostics/issues/941

* Issue https://github.com/dotnet/diagnostics/issues/942

* Fix sosstatus runtime size display

src/SOS/SOS.Hosting/SOSHost.cs
src/SOS/Strike/hostcoreclr.cpp
src/SOS/Strike/runtime.cpp
src/SOS/Strike/strike.cpp
src/Tools/dotnet-dump/Analyzer.cs
src/Tools/dotnet-dump/Commands/ExitCommand.cs
src/Tools/dotnet-dump/Commands/SOSCommand.cs
src/Tools/dotnet-dump/Commands/SetClrPathCommand.cs

index b117953d57e77075e96097424c1e30288d869e0f..e6ede145ab3a3552e822df21a445af54b2e59d4d 100644 (file)
@@ -38,6 +38,7 @@ namespace SOS
             [In, MarshalAs(UnmanagedType.Struct)] ref SOSNetCoreCallbacks callbacks,
             int callbacksSize,
             [In, MarshalAs(UnmanagedType.LPStr)] string tempDirectory,
+            [In, MarshalAs(UnmanagedType.LPStr)] string runtimeModulePath,
             bool isDesktop,
             [In, MarshalAs(UnmanagedType.LPStr)] string dacFilePath,
             [In, MarshalAs(UnmanagedType.LPStr)] string dbiFilePath,
@@ -258,6 +259,7 @@ namespace SOS
                     ref s_callbacks,
                     Marshal.SizeOf<SOSNetCoreCallbacks>(),
                     tempDirectory,
+                    AnalyzeContext.RuntimeModuleDirectory,
                     isDesktop,
                     dacFilePath,
                     dbiFilePath,
index 1e791369cb99d0b0f8685f160f17387eaef020ae..894a802303c4ab28f9fe4036c71c938a75f86dff 100644 (file)
@@ -347,18 +347,18 @@ static HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntime
 #endif // FEATURE_PAL
         hostRuntimeDirectory.append(DIRECTORY_SEPARATOR_STR_A);
 
-        // First attempt find the highest 2.1.x version. We want to start with the LTS
+        // First attempt find the highest LTS version. We want to start with the LTSs
         // and only use the higher versions if it isn't installed.
-        if (!FindDotNetVersion(2, 1, hostRuntimeDirectory))
+        if (!FindDotNetVersion(3, 1, hostRuntimeDirectory))
         {
-            // Find highest 2.2.x version
-            if (!FindDotNetVersion(2, 2, hostRuntimeDirectory))
+            // Find highest 2.1 LTS version
+            if (!FindDotNetVersion(2, 1, hostRuntimeDirectory))
             {
                 // Find highest 3.0.x version
                 if (!FindDotNetVersion(3, 0, hostRuntimeDirectory))
                 {
-                    // Find highest 3.1.x version
-                    if (!FindDotNetVersion(3, 1, hostRuntimeDirectory))
+                    // Find highest 2.2.x version
+                    if (!FindDotNetVersion(2, 2, hostRuntimeDirectory))
                     {
                         // Find highest 5.0.x version
                         if (!FindDotNetVersion(5, 0, hostRuntimeDirectory))
@@ -458,7 +458,15 @@ void CleanupTempDirectory()
 /**********************************************************************\
  * Called when the managed SOS Host loads/initializes SOS.
 \**********************************************************************/
-extern "C" HRESULT SOSInitializeByHost(SOSNetCoreCallbacks* callbacks, int callbacksSize, LPCSTR tempDirectory, bool isDesktop, LPCSTR dacFilePath, LPCSTR dbiFilePath, bool symbolStoreEnabled)
+extern "C" HRESULT SOSInitializeByHost(
+    SOSNetCoreCallbacks* callbacks,
+    int callbacksSize,
+    LPCSTR tempDirectory,
+    LPCSTR runtimeModulePath,
+    bool isDesktop,
+    LPCSTR dacFilePath,
+    LPCSTR dbiFilePath,
+    bool symbolStoreEnabled)
 {
     if (memcpy_s(&g_SOSNetCoreCallbacks, sizeof(g_SOSNetCoreCallbacks), callbacks, callbacksSize) != 0)
     {
@@ -468,6 +476,10 @@ extern "C" HRESULT SOSInitializeByHost(SOSNetCoreCallbacks* callbacks, int callb
     {
         g_tmpPath = _strdup(tempDirectory);
     }
+    if (runtimeModulePath != nullptr)
+    {
+        g_runtimeModulePath = _strdup(runtimeModulePath);
+    }
     Runtime::SetDacDbiPath(isDesktop, dacFilePath, dbiFilePath);
 #ifndef FEATURE_PAL
     // When SOS is hosted on dotnet-dump, the ExtensionApis are not set so 
index 60004e8e12b3b5c11ff054f2ed9a87536934d048..940863c20d370b4900d1ab9ac01b17f60719b6b5 100644 (file)
@@ -525,7 +525,7 @@ HRESULT Runtime::GetCorDebugInterface(ICorDebugProcess** ppCorDebugProcess)
 \**********************************************************************/
 void Runtime::DisplayStatus()
 {
-    ExtOut("%s runtime at %p (%08x)\n", GetRuntimeConfigurationName(GetRuntimeConfiguration()), m_address, m_size);
+    ExtOut("%s runtime at %p size %08llx\n", GetRuntimeConfigurationName(GetRuntimeConfiguration()), m_address, m_size);
     if (m_runtimeDirectory != nullptr) {
         ExtOut("Runtime directory: %s\n", m_runtimeDirectory);
     }
index 899edb07e62798d8392b3c5c4d2b8a810c37b2c6..091a42e83b1716e52a2e202d2d9d8518d6fd3ea1 100644 (file)
@@ -1359,6 +1359,8 @@ DECLARE_API(DumpMT)
 
     table.WriteRow("BaseSize:", PrefixHex(vMethTable.BaseSize));
     table.WriteRow("ComponentSize:", PrefixHex(vMethTable.ComponentSize));
+    table.WriteRow("DynamicStatics:", vMethTable.bIsDynamic ? "true" : "false");
+    table.WriteRow("ContainsPointers:", vMethTable.bContainsPointers ? "true" : "false");
     table.WriteRow("Slots in VTable:", Decimal(vMethTable.wNumMethods));
     
     table.SetColWidth(0, 29);
index ed93268e0cdf4e51d26a8afbce785906c6ebc505..f01feec475a26060dda81bb7c6ce77816e59ea3a 100644 (file)
@@ -222,53 +222,67 @@ namespace Microsoft.Diagnostics.Tools.Dump
         private string GetDacFile(ClrInfo clrInfo)
         {
             if (_dacFilePath == null)
-            {
-                string dac = clrInfo.LocalMatchingDac;
-                if (dac != null && File.Exists(dac))
+            {            
+                Debug.Assert(!string.IsNullOrEmpty(clrInfo.DacInfo.FileName));
+                var analyzeContext = _serviceProvider.GetService<AnalyzeContext>();
+                string dacFilePath = null;
+                if (!string.IsNullOrEmpty(analyzeContext.RuntimeModuleDirectory))
                 {
-                    _dacFilePath = dac;
+                    dacFilePath = Path.Combine(analyzeContext.RuntimeModuleDirectory, clrInfo.DacInfo.FileName);
+                    if (File.Exists(dacFilePath))
+                    {
+                        _dacFilePath = dacFilePath;
+                    }
                 }
-                else if (SymbolReader.IsSymbolStoreEnabled())
+                if (_dacFilePath == null)
                 {
-                    string dacFileName = Path.GetFileName(dac ?? clrInfo.DacInfo.FileName);
-                    if (dacFileName != null)
+                    dacFilePath = clrInfo.LocalMatchingDac;
+                    if (!string.IsNullOrEmpty(dacFilePath) && File.Exists(dacFilePath))
                     {
-                        SymbolStoreKey key = null;
-
-                        if (clrInfo.ModuleInfo.BuildId != null)
+                        _dacFilePath = dacFilePath;
+                    }
+                    else if (SymbolReader.IsSymbolStoreEnabled())
+                    {
+                        string dacFileName = Path.GetFileName(dacFilePath ?? clrInfo.DacInfo.FileName);
+                        if (dacFileName != null)
                         {
-                            IEnumerable<SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
-                                KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);
+                            SymbolStoreKey key = null;
+
+                            if (clrInfo.ModuleInfo.BuildId != null)
+                            {
+                                IEnumerable<SymbolStoreKey> keys = ELFFileKeyGenerator.GetKeys(
+                                    KeyTypeFlags.ClrKeys, clrInfo.ModuleInfo.FileName, clrInfo.ModuleInfo.BuildId, symbolFile: false, symbolFileName: null);
 
-                            key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
+                                key = keys.SingleOrDefault((k) => Path.GetFileName(k.FullPathName) == dacFileName);
 
-                            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+                                {
+                                    // We are opening a Linux dump on Windows
+                                    // We need to use the Windows index and filename
+                                    key = new SymbolStoreKey(key.Index.Replace("libmscordaccore.so", "mscordaccore.dll"),
+                                                             key.FullPathName.Replace("libmscordaccore.so", "mscordaccore.dll"),
+                                                             key.IsClrSpecialFile,
+                                                             key.PdbChecksums);
+                                }
+                            }
+                            else
                             {
-                                // We are opening a Linux dump on Windows
-                                // We need to use the Windows index and filename
-                                key = new SymbolStoreKey(key.Index.Replace("libmscordaccore.so", "mscordaccore.dll"),
-                                                         key.FullPathName.Replace("libmscordaccore.so", "mscordaccore.dll"),
-                                                         key.IsClrSpecialFile,
-                                                         key.PdbChecksums);
+                                // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
+                                key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
                             }
-                        }
-                        else
-                        {
-                            // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
-                            key = PEFileKeyGenerator.GetKey(dacFileName, clrInfo.ModuleInfo.TimeStamp, clrInfo.ModuleInfo.FileSize);
-                        }
 
-                        if (key != null)
-                        {
-                            // Now download the DAC module from the symbol server
-                            _dacFilePath = SymbolReader.GetSymbolFile(key);
+                            if (key != null)
+                            {
+                                // Now download the DAC module from the symbol server
+                                _dacFilePath = SymbolReader.GetSymbolFile(key);
+                            }
                         }
                     }
-                }
 
-                if (_dacFilePath == null)
-                {
-                    throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
+                    if (_dacFilePath == null)
+                    {
+                        throw new FileNotFoundException($"Could not find matching DAC for this runtime: {clrInfo.ModuleInfo.FileName}");
+                    }
                 }
                 _isDesktop = clrInfo.Flavor == ClrFlavor.Desktop;
             }
index 1c249c42420d2177442d16abd9fd4d3e1b956d56..d0acc7aac0e64c6ec0df9c548817db88685053b5 100644 (file)
@@ -10,6 +10,7 @@ namespace Microsoft.Diagnostics.Tools.Dump
 {
     [Command(Name = "exit", Help = "Exit interactive mode.")]
     [CommandAlias(Name = "quit")]
+    [CommandAlias(Name = "q")]
     public class ExitCommand : CommandBase
     {
         public override void Invoke()
index 2bb9c8d60ad54815eb75b8a3b9f510cecf21e9c3..639693eb5dd4cc93f84d4f2bc364052fe7e2cbc5 100644 (file)
@@ -48,7 +48,6 @@ namespace Microsoft.Diagnostics.Tools.Dump
     [Command(Name = "histobjfind",      AliasExpansion = "HistObjFind",         Help = "Displays all the log entries that reference an object at the specified address.")]
     [Command(Name = "histroot",         AliasExpansion = "HistRoot",            Help = "Displays information related to both promotions and relocations of the specified root.")]
     [Command(Name = "setsymbolserver",  AliasExpansion = "SetSymbolServer",     Help = "Enables the symbol server support ")]
-    [Command(Name = "setclrpath",       AliasExpansion = "setclrpath",          Platform = CommandPlatform.Windows, Help = "Set the path to load the runtime DAC/DBI files.")]
     [Command(Name = "dumprcw",          AliasExpansion = "DumpRCW",             Platform = CommandPlatform.Windows, Help = "Displays information about a Runtime Callable Wrapper.")]
     [Command(Name = "dumpccw",          AliasExpansion = "DumpCCW",             Platform = CommandPlatform.Windows, Help = "Displays information about a COM Callable Wrapper.")]
     [Command(Name = "dumppermissionset",AliasExpansion = "DumpPermissionSet",   Platform = CommandPlatform.Windows, Help = "Displays a PermissionSet object (debug build only).")]
index e59fd3bef85612ef184216953fc5a4ce0d5882ca..250b1b2deb652ecf975e70f640776aacbbbc72f3 100644 (file)
@@ -8,7 +8,7 @@ using System.CommandLine;
 
 namespace Microsoft.Diagnostics.Tools.Dump
 {
-    [Command(Name = "setclrpath", Platform = CommandPlatform.Linux | CommandPlatform.OSX, Help = "Set the path to load coreclr DAC/DBI files.")]
+    [Command(Name = "setclrpath", Help = "Set the path to load coreclr DAC/DBI files.")]
     public class SetClrPath: CommandBase
     {
         public AnalyzeContext AnalyzeContext { get; set; }