Use clrmd single-file support. (#2130)
authorMike McLaughlin <mikem@microsoft.com>
Fri, 2 Apr 2021 00:12:18 +0000 (17:12 -0700)
committerGitHub <noreply@github.com>
Fri, 2 Apr 2021 00:12:18 +0000 (17:12 -0700)
Fix edge cases enumerating modules and assemblies

Don't provide a BinaryLocator to clrmd anymore; not needed

Remove ParallelStacks.Runtime references

dotnet-dump now provides IExportSymbols on linux modules.

12 files changed:
THIRD-PARTY-NOTICES.TXT
eng/Version.Details.xml
eng/Versions.props
src/Microsoft.Diagnostics.DebugServices.Implementation/BinaryLocator.cs [deleted file]
src/Microsoft.Diagnostics.DebugServices.Implementation/ImageMappingMemoryService.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/ModuleService.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/ModuleServiceFromDataReader.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/Runtime.cs
src/Microsoft.Diagnostics.DebugServices.Implementation/RuntimeService.cs
src/Microsoft.Diagnostics.DebugServices/MemoryServiceExtensions.cs
src/Microsoft.Diagnostics.ExtensionCommands/ClrModulesCommand.cs
src/Microsoft.Diagnostics.ExtensionCommands/Microsoft.Diagnostics.ExtensionCommands.csproj

index 6f946d5f28ef35f30d9b2e4116d3c873a26e4b2e..29cb3d06d3f41aa1dfed6a238840c6c0109386d2 100644 (file)
@@ -298,30 +298,3 @@ This set of code is covered by the following license:
     See the License for the specific language governing permissions and
     limitations under the License.
 
-License notice for ParallelStacks.Runtime
------------------------------------------
-
-Source found at https://github.com/chrisnas/DebuggingExtensions
-
-MIT License
-
-Copyright (c) 2016-2019 Nasarre Christophe
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
index e412ace34e8cf83129c2c58dd0b89032bbea6976..a685c9fa52f484004f55ac1b85ef0d78757c1fde 100644 (file)
@@ -8,11 +8,11 @@
       <Uri>https://github.com/dotnet/symstore</Uri>
       <Sha>3ed87724fe4e98c7ecc77617720591783ee2e676</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.Diagnostics.Runtime" Version="2.0.216202">
+    <Dependency Name="Microsoft.Diagnostics.Runtime" Version="2.0.218001">
       <Uri>https://github.com/Microsoft/clrmd</Uri>
       <Sha>8b1eadaa0dd50fdd05419764f5606914da56ac9e</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.Diagnostics.Runtime.Utilities" Version="2.0.216202">
+    <Dependency Name="Microsoft.Diagnostics.Runtime.Utilities" Version="2.0.218001">
       <Uri>https://github.com/Microsoft/clrmd</Uri>
       <Sha>8b1eadaa0dd50fdd05419764f5606914da56ac9e</Sha>
     </Dependency>
index 368e58926b021072c1a10b185bffc965d30a1312..ee8ab6ed50ea853f7fd913fc6985d27e34eb4736 100644 (file)
@@ -36,9 +36,8 @@
     <MicrosoftWin32PrimitivesVersion>4.3.0</MicrosoftWin32PrimitivesVersion>
     <!-- Other libs -->
     <MicrosoftBclAsyncInterfacesVersion>1.1.0</MicrosoftBclAsyncInterfacesVersion>
-    <MicrosoftDiagnosticsRuntimeVersion>2.0.216202</MicrosoftDiagnosticsRuntimeVersion>
-    <MicrosoftDiagnosticsRuntimeUtilitiesVersion>2.0.216202</MicrosoftDiagnosticsRuntimeUtilitiesVersion>
-    <ParallelStacksRuntimeVersion>2.0.1</ParallelStacksRuntimeVersion>
+    <MicrosoftDiagnosticsRuntimeVersion>2.0.218001</MicrosoftDiagnosticsRuntimeVersion>
+    <MicrosoftDiagnosticsRuntimeUtilitiesVersion>2.0.218001</MicrosoftDiagnosticsRuntimeUtilitiesVersion>
     <MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
     <MicrosoftDiagnosticsTracingTraceEventVersion>2.0.64</MicrosoftDiagnosticsTracingTraceEventVersion>
     <MicrosoftExtensionsLoggingVersion>2.1.1</MicrosoftExtensionsLoggingVersion>
diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/BinaryLocator.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/BinaryLocator.cs
deleted file mode 100644 (file)
index db4e5e6..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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 Microsoft.Diagnostics.Runtime;
-using Microsoft.SymbolStore;
-using Microsoft.SymbolStore.KeyGenerators;
-using System.Collections.Immutable;
-using System.Diagnostics;
-using System.Threading.Tasks;
-
-namespace Microsoft.Diagnostics.DebugServices.Implementation
-{
-#nullable enable
-
-    /// <summary>
-    /// A ClrMD symbol locator that search binaries based on files loaded in the live Linux target.
-    /// </summary>
-    internal class BinaryLocator : IBinaryLocator
-    {
-        private readonly ISymbolService _symbolService;
-
-        public BinaryLocator(ITarget target)
-        {
-            _symbolService = target.Services.GetService<ISymbolService>();
-        }
-
-        public string? FindBinary(string fileName, int buildTimeStamp, int imageSize, bool checkProperties)
-        {
-            Trace.TraceInformation($"FindBinary: {fileName} buildTimeStamp {buildTimeStamp:X8} imageSize {imageSize:X8}");
-
-            if (_symbolService.IsSymbolStoreEnabled)
-            {
-                SymbolStoreKey? key = PEFileKeyGenerator.GetKey(fileName, (uint)buildTimeStamp, (uint)imageSize);
-                if (key != null)
-                {
-                    // Now download the module from the symbol server, cache or from a directory
-                    return _symbolService.DownloadFile(key);
-                }
-                else
-                {
-                    Trace.TraceInformation($"FindBinary: {fileName}: key not generated");
-                }
-            }
-            else
-            {
-                Trace.TraceInformation($"FindBinary: {fileName}: symbol store not enabled");
-            }
-
-            return null;
-        }
-
-        public string? FindBinary(string fileName, ImmutableArray<byte> buildId, bool checkProperties)
-        {
-            Trace.TraceInformation($"FindBinary: {fileName} buildid {buildId}");
-            return null;
-        }
-
-        public Task<string?> FindBinaryAsync(string fileName, ImmutableArray<byte> buildId, bool checkProperties)
-        {
-            Trace.TraceInformation($"FindBinaryAsync: {fileName} buildid {buildId}");
-            return Task.FromResult<string?>(null);
-        }
-
-        public Task<string?> FindBinaryAsync(string fileName, int buildTimeStamp, int imageSize, bool checkProperties)
-        {
-            Trace.TraceInformation($"FindBinaryAsync: {fileName} buildTimeStamp {buildTimeStamp:X8} imageSize {imageSize:X8}");
-            return Task.FromResult<string?>(null);
-        }
-    }
-}
index fd69cf6bda362497ef48c24022e43becf2e5a395..5a65d80edeabbf51bffa314ab1bbefa04b062cb0 100644 (file)
@@ -137,6 +137,10 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                                         data = block.GetReader().ReadBytes(size);
                                         ApplyRelocations(module, reader, rva, data);
                                     }
+                                    else
+                                    {
+                                        Trace.TraceError($"ReadMemory: FAILED rva {rva:X8}");
+                                    }
                                 }
 
                                 return data;
@@ -167,6 +171,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                                 uint read = virtualAddressReader.Read(rva, data, 0, (uint)bytesRequested);
                                 if (read == 0)
                                 {
+                                    Trace.TraceError($"ReadMemory: FAILED rva {rva:X8}");
                                     data = null;
                                 }
                                 return data;
@@ -183,6 +188,10 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                         _recursionProtection.Remove(module.ImageBase);
                     }
                 }
+                else
+                {
+                    Trace.TraceError("ReadMemory: recursion");
+                }
             }
             return null;
         }
index 6602589d97f6cd9c9728d85f6e4fe7bbc827fc11..017dde7171d75619195e96acce5ead876ef42f8a 100644 (file)
@@ -292,18 +292,23 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             }
             else 
             { 
-                if (SymbolService.IsSymbolStoreEnabled)
+                if (module.IndexTimeStamp.HasValue && module.IndexFileSize.HasValue)
                 {
-                    if (module.IndexTimeStamp.HasValue && module.IndexFileSize.HasValue)
+                    SymbolStoreKey key = PEFileKeyGenerator.GetKey(Path.GetFileName(module.FileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value);
+                    if (key is not null)
                     {
-                        SymbolStoreKey key = PEFileKeyGenerator.GetKey(Path.GetFileName(module.FileName), module.IndexTimeStamp.Value, module.IndexFileSize.Value);
-                        if (key != null)
-                        {
-                            // Now download the module from the symbol server
-                            downloadFilePath = SymbolService.DownloadFile(key);
-                        }
+                        // Now download the module from the symbol server
+                        downloadFilePath = SymbolService.DownloadFile(key);
+                    }
+                    else
+                    {
+                        Trace.TraceWarning($"GetPEReader: no index generated for module {module.FileName} ");
                     }
                 }
+                else
+                {
+                    Trace.TraceWarning($"GetPEReader: module {module.FileName} has no index timestamp/filesize");
+                }
             }
 
             if (!string.IsNullOrEmpty(downloadFilePath))
@@ -324,6 +329,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                     reader = new PEReader(stream);
                     if (reader.PEHeaders == null || reader.PEHeaders.PEHeader == null)
                     {
+                        Trace.TraceError($"GetPEReader: PEReader invalid headers");
                         return null;
                     }
                 }
@@ -354,18 +360,23 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             }
             else 
             { 
-                if (SymbolService.IsSymbolStoreEnabled)
+                if (!module.BuildId.IsDefaultOrEmpty)
                 {
-                    if (!module.BuildId.IsDefaultOrEmpty)
+                    SymbolStoreKey key = ELFFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
+                    if (key is not null)
                     {
-                        var key = ELFFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
-                        if (key != null)
-                        {
-                            // Now download the module from the symbol server
-                            downloadFilePath = SymbolService.DownloadFile(key);
-                        }
+                        // Now download the module from the symbol server
+                        downloadFilePath = SymbolService.DownloadFile(key);
+                    }
+                    else
+                    {
+                        Trace.TraceWarning($"GetELFFile: no index generated for module {module.FileName} ");
                     }
                 }
+                else
+                {
+                    Trace.TraceWarning($"GetELFFile: module {module.FileName} has no build id");
+                }
             }
 
             if (!string.IsNullOrEmpty(downloadFilePath))
@@ -386,6 +397,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                     elfFile = new ELFFile(new StreamAddressSpace(stream), position: 0, isDataSourceVirtualAddressSpace: false);
                     if (!elfFile.IsValid())
                     {
+                        Trace.TraceError($"GetELFFile: not a valid file");
                         return null;
                     }
                 }
@@ -416,17 +428,22 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             }
             else 
             { 
-                if (SymbolService.IsSymbolStoreEnabled)
+                if (!module.BuildId.IsDefaultOrEmpty)
                 {
-                    if (!module.BuildId.IsDefaultOrEmpty)
+                    SymbolStoreKey key = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
+                    if (key is not null)
                     {
-                        var key = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.IdentityKey, module.FileName, module.BuildId.ToArray(), symbolFile: false, symbolFileName: null).SingleOrDefault();
-                        if (key != null)
-                        {
-                            // Now download the module from the symbol server
-                            downloadFilePath = SymbolService.DownloadFile(key);
-                        }
+                        // Now download the module from the symbol server
+                        downloadFilePath = SymbolService.DownloadFile(key);
                     }
+                    else
+                    {
+                        Trace.TraceWarning($"GetMachOFile: no index generated for module {module.FileName} ");
+                    }
+                }
+                else
+                {
+                    Trace.TraceWarning($"GetMachOFile: module {module.FileName} has no index timestamp/filesize");
                 }
             }
 
@@ -448,6 +465,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                     machoFile = new MachOFile(new StreamAddressSpace(stream), position: 0, dataSourceIsVirtualAddressSpace: false);
                     if (!machoFile.IsValid())
                     {
+                        Trace.TraceError($"GetMachOFile: not a valid file");
                         return null;
                     }
                 }
index f66894c3121fbf1f0fcb355fa4871aa2f62af2a8..de57074fcdf12a5c7737f1a9499a1791d5728247 100644 (file)
@@ -16,24 +16,30 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
     /// </summary>
     public class ModuleServiceFromDataReader : ModuleService
     {
-        class ModuleFromDataReader : Module
+        class ModuleFromDataReader : Module, IExportSymbols
         {
             // This is what clrmd returns for non-PE modules that don't have a timestamp
             private const uint InvalidTimeStamp = 0;
 
             private static readonly VersionInfo EmptyVersionInfo = new VersionInfo(0, 0, 0, 0);
             private readonly ModuleServiceFromDataReader _moduleService;
+            private readonly IExportReader _exportReader;
             private readonly ModuleInfo _moduleInfo;
             private readonly ulong _imageSize;
             private string _versionString;
 
-            public ModuleFromDataReader(ModuleServiceFromDataReader moduleService, int moduleIndex, ModuleInfo moduleInfo, ulong imageSize)
+            public ModuleFromDataReader(ModuleServiceFromDataReader moduleService, IExportReader exportReader, int moduleIndex, ModuleInfo moduleInfo, ulong imageSize)
                 : base(moduleService.Target)
             {
                 _moduleService = moduleService;
                 _moduleInfo = moduleInfo;
                 _imageSize = imageSize;
+                _exportReader = exportReader;
                 ModuleIndex = moduleIndex;
+                if (exportReader is not null)
+                {
+                    ServiceProvider.AddService<IExportSymbols>(this);
+                }
             }
 
             #region IModule
@@ -89,6 +95,20 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
             #endregion
 
+            #region IExportSymbols
+
+            public bool TryGetSymbolAddress(string name, out ulong address)
+            {
+                if (_exportReader is not null)
+                {
+                    return _exportReader.TryGetSymbolAddress(ImageBase, name, out address);
+                }
+                address = 0;
+                return false;
+            }
+
+            #endregion
+
             protected override ModuleService ModuleService => _moduleService;
         }
 
@@ -108,6 +128,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             var modules = new Dictionary<ulong, IModule>();
             int moduleIndex = 0;
 
+            IExportReader exportReader = _dataReader as IExportReader;
             ModuleInfo[] moduleInfos = _dataReader.EnumerateModules().OrderBy((info) => info.ImageBase).ToArray();
             for (int i = 0; i < moduleInfos.Length; i++)
             {
@@ -127,7 +148,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                         imageSize = startNext - start;
                     }
                 }
-                var module = new ModuleFromDataReader(this, moduleIndex, moduleInfo, imageSize);
+                var module = new ModuleFromDataReader(this, exportReader, moduleIndex, moduleInfo, imageSize);
                 try
                 {
                     modules.Add(moduleInfo.ImageBase, module);
index 2166bf21ec3091d5342e5bc9454fface5fc759f2..d6396c688ed4c0e00b0500ceae1f9676ff8256ed 100644 (file)
@@ -68,11 +68,11 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
         public string GetDacFilePath()
         {
-            if (_dacFilePath == null)
+            if (_dacFilePath is null)
             {
                 string dacFileName = GetDacFileName();
                 _dacFilePath = GetLocalDacPath(dacFileName);
-                if (_dacFilePath == null)
+                if (_dacFilePath is null)
                 {
                     _dacFilePath = DownloadFile(dacFileName);
                 }
@@ -82,11 +82,11 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
         public string GetDbiFilePath()
         {
-            if (_dbiFilePath == null)
+            if (_dbiFilePath is null)
             {
                 string dbiFileName = GetDbiFileName();
                 _dbiFilePath = GetLocalPath(dbiFileName);
-                if (_dbiFilePath == null)
+                if (_dbiFilePath is null)
                 {
                     _dbiFilePath = DownloadFile(dbiFileName);
                 }
@@ -101,10 +101,10 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         /// </summary>
         private ClrRuntime CreateRuntime()
         {
-            if (_clrRuntime == null)
+            if (_clrRuntime is null)
             {
                 string dacFilePath = GetDacFilePath();
-                if (dacFilePath != null)
+                if (dacFilePath is not null)
                 {
                     Trace.TraceInformation($"Creating ClrRuntime #{Id} {dacFilePath}");
                     try
@@ -209,10 +209,10 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
                 if (platform == OSPlatform.Windows)
                 {
-                    // Use the coreclr.dll's id (timestamp/filesize) to download the the dac module.
-                    if (RuntimeModule.IndexTimeStamp.HasValue && RuntimeModule.IndexFileSize.HasValue)
+                    // It is the coreclr.dll's id (timestamp/filesize) in the DacInfo used to download the the dac module.
+                    if (_clrInfo.DacInfo.IndexTimeStamp != 0 && _clrInfo.DacInfo.IndexFileSize != 0)
                     {
-                        key = PEFileKeyGenerator.GetKey(fileName, RuntimeModule.IndexTimeStamp.Value, RuntimeModule.IndexFileSize.Value);
+                        key = PEFileKeyGenerator.GetKey(fileName, (uint)_clrInfo.DacInfo.IndexTimeStamp, (uint)_clrInfo.DacInfo.IndexFileSize);
                     }
                     else
                     {
@@ -222,17 +222,18 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                 else
                 {
                     // Use the runtime's build id to download the the dac module.
-                    if (!RuntimeModule.BuildId.IsDefaultOrEmpty)
+                    if (!_clrInfo.DacInfo.ClrBuildId.IsDefaultOrEmpty)
                     {
+                        byte[] buildId = _clrInfo.DacInfo.ClrBuildId.ToArray();
                         IEnumerable<SymbolStoreKey> keys = null;
 
                         if (platform == OSPlatform.Linux)
                         {
-                            keys = ELFFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, RuntimeModule.FileName, RuntimeModule.BuildId.ToArray(), symbolFile: false, symbolFileName: null);
+                            keys = ELFFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, "libcoreclr.so", buildId, symbolFile: false, symbolFileName: null);
                         }
                         else if (platform == OSPlatform.OSX)
                         {
-                            keys = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, RuntimeModule.FileName, RuntimeModule.BuildId.ToArray(), symbolFile: false, symbolFileName: null);
+                            keys = MachOFileKeyGenerator.GetKeys(KeyTypeFlags.DacDbiKeys, "libcoreclr.dylib", buildId, symbolFile: false, symbolFileName: null);
                         }
                         else
                         {
@@ -247,7 +248,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                     }
                 }
 
-                if (key != null)
+                if (key is not null)
                 {
                     // Now download the DAC module from the symbol server
                     filePath = SymbolService.DownloadFile(key);
@@ -284,11 +285,16 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
             var sb = new StringBuilder();
             string config = s_runtimeTypeNames[(int)RuntimeType];
             sb.AppendLine($"#{Id} {config} runtime at {RuntimeModule.ImageBase:X16} size {RuntimeModule.ImageSize:X8}");
-            sb.AppendLine($"    Runtime module path: {RuntimeModule.FileName}");
-            if (_dacFilePath != null) {
+            if (_clrInfo.SingleFileRuntimeInfo.HasValue) {
+                sb.AppendLine($"    Single-file runtime module path: {RuntimeModule.FileName}");
+            }
+            else {
+                sb.AppendLine($"    Runtime module path: {RuntimeModule.FileName}");
+            }
+            if (_dacFilePath is not null) {
                 sb.AppendLine($"    DAC: {_dacFilePath}");
             }
-            if (_dbiFilePath != null) {
+            if (_dbiFilePath is not null) {
                 sb.AppendLine($"    DBI: {_dbiFilePath}");
             }
             return sb.ToString();
index d87748838a59550f49f6d081d18ab2f91bab237c..6949fff5c19ee30d445d4936947e630ad1b07af9 100644 (file)
@@ -18,7 +18,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
     /// <summary>
     /// ClrMD runtime service implementation
     /// </summary>
-    public class RuntimeService : IRuntimeService, IDataReader
+    public class RuntimeService : IRuntimeService, IDataReader, IExportReader
     {
         private readonly ITarget _target;
         private readonly IDisposable _onFlushEvent;
@@ -34,7 +34,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         {
             _target = target;
             _onFlushEvent = target.OnFlushEvent.Register(() => {
-                if (_runtimes != null && _runtimes.Count == 0)
+                if (_runtimes is not null && _runtimes.Count == 0)
                 {
                     // If there are no runtimes, try find them again when the target stops
                     _runtimes = null;
@@ -80,7 +80,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         {
             get
             {
-                if (_currentRuntime == null) {
+                if (_currentRuntime is null) {
                     _currentRuntime = FindRuntime();
                 }
                 return _currentRuntime;
@@ -93,7 +93,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         /// <param name="runtimeId">runtime id</param>
         public void SetCurrentRuntime(int runtimeId)
         {
-            if (_runtimes == null || runtimeId >= _runtimes.Count) {
+            if (_runtimes is null || runtimeId >= _runtimes.Count) {
                 throw new DiagnosticsException($"Invalid runtime id {runtimeId}");
             }
             _currentRuntime = _runtimes[runtimeId];
@@ -231,6 +231,27 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
         #endregion
 
+        #region IExportReader
+
+        bool IExportReader.TryGetSymbolAddress(ulong baseAddress, string name, out ulong offset)
+        {
+            try
+            {
+                IExportSymbols exportSymbols = ModuleService.GetModuleFromBaseAddress(baseAddress).Services.GetService<IExportSymbols>();
+                if (exportSymbols is not null)
+                {
+                    return exportSymbols.TryGetSymbolAddress(name, out offset);
+                }
+            }
+            catch (DiagnosticsException)
+            {
+            }
+            offset = 0;
+            return false;
+        }
+
+        #endregion
+
         /// <summary>
         /// Find the runtime
         /// </summary>
@@ -249,7 +270,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
                 }
             }
             // If no .NET Core runtime, then check for desktop runtime
-            if (runtime == null)
+            if (runtime is null)
             {
                 foreach (Runtime r in runtimes)
                 {
@@ -265,16 +286,18 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
 
         private IEnumerable<Runtime> BuildRuntimes()
         {
-            if (_runtimes == null)
+            if (_runtimes is null)
             {
                 _runtimes = new List<Runtime>();
-                if (_dataTarget == null)
+                if (_dataTarget is null)
                 {
-                    _dataTarget = new DataTarget(new CustomDataTarget(this) {
-                        BinaryLocator = new BinaryLocator(_target)
-                    });
+                    // Don't use the default binary locator or provide one. clrmd uses it to download the DAC, download assemblies
+                    // to get metadata in its data target or for invalid memory region mapping and we already do all of that.
+                    _dataTarget = new DataTarget(new CustomDataTarget(this)) {
+                        BinaryLocator = null
+                    };
                 }
-                if (_dataTarget != null)
+                if (_dataTarget is not null)
                 {
                     for (int i = 0; i < _dataTarget.ClrVersions.Length; i++)
                     {
@@ -294,10 +317,10 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
         public override string ToString()
         {
             var sb = new StringBuilder();
-            if (_runtimeModuleDirectory != null) {
+            if (_runtimeModuleDirectory is not null) {
                 sb.AppendLine($"Runtime module path: {_runtimeModuleDirectory}");
             }
-            if (_runtimes != null)
+            if (_runtimes is not null)
             {
                 foreach (IRuntime runtime in _runtimes)
                 {
index 8f3a059b171ca87448d098bd4fc41f5714ac0fbc..2fba2bb1c615d2bddc11453026f538be3c75a2c1 100644 (file)
@@ -144,7 +144,7 @@ namespace Microsoft.Diagnostics.DebugServices
             public override int Read(byte[] buffer, int offset, int count)
             {
                 if (Position + count > Length) {
-                    throw new ArgumentOutOfRangeException();
+                    return 0;
                 }
                 if (_memoryService.ReadMemory(_address + (ulong)Position, new Span<byte>(buffer, offset, count), out int bytesRead)) {
                     Position += bytesRead;
index 1ae52e8a145a23bd23080f6e11ba0ea41495a85e..20c7dc879c306a87aa78df1060badbf63b3ac2de 100644 (file)
@@ -5,6 +5,7 @@
 using Microsoft.Diagnostics.DebugServices;
 using Microsoft.Diagnostics.Runtime;
 using System;
+using System.Linq;
 
 namespace Microsoft.Diagnostics.ExtensionCommands
 {
@@ -28,7 +29,7 @@ namespace Microsoft.Diagnostics.ExtensionCommands
             {
                 if (Verbose)
                 {
-                    WriteLine("{0}", module.Name);
+                    WriteLine("{0}{1}", module.Name, module.IsDynamic ? "(Dynamic)" : "");
                     WriteLine("    AssemblyName:    {0}", module.AssemblyName);
                     WriteLine("    ImageBase:       {0:X16}", module.ImageBase);
                     WriteLine("    Size:            {0:X8}", module.Size);
@@ -51,7 +52,7 @@ namespace Microsoft.Diagnostics.ExtensionCommands
                 }
                 else
                 {
-                    WriteLine("{0:X16} {1:X8} {2}", module.ImageBase, module.Size, module.Name);
+                    WriteLine("{0:X16} {1:X8} {2}{3}", module.ImageBase, module.Size, module.Name, module.IsDynamic ? "(Dynamic)" : "");
                 }
             }
         }
index 4a47509c5f2f5ddbd24c44445d413cbeeb6ecd41..c919c419e46b7db91105795432938eea8fcd0150 100644 (file)
@@ -20,8 +20,4 @@
   <ItemGroup>
     <ProjectReference Include="..\Microsoft.Diagnostics.DebugServices\Microsoft.Diagnostics.DebugServices.csproj" />
   </ItemGroup>
-
-  <ItemGroup>
-    <Folder Include="ParallelStacks.Runtime\" />
-  </ItemGroup>
 </Project>