Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes needed for clrmd 2.1 #3094

Merged
5 commits merged into from
Jun 12, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions eng/CodeAnalysis.ruleset
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<RuleSet Name="Diagnostics Ruleset"
Description="Diagnostics Ruleset"
ToolsVersion="14.0">

<!-- Define all the analyzer rule actions for this repo. -->
<Include Path="CodeAnalysis.Repository.ruleset" Action="Default" />

<!-- This will override or define all rules needed values to be SDL compliant. -->
<Include Path="CodeAnalysis.Security.ruleset" Action="Default" />
</RuleSet>
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Diagnostics Ruleset" Description="Diagnostics Ruleset" ToolsVersion="14.0">
<!-- Define all the analyzer rule actions for this repo. -->
<Include Path="CodeAnalysis.Repository.ruleset" Action="Default" />
<!-- This will override or define all rules needed values to be SDL compliant. -->
<Include Path="CodeAnalysis.Security.ruleset" Action="Default" />
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
<Rule Id="CA1069" Action="None" />
</Rules>
</RuleSet>
4 changes: 2 additions & 2 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<Uri>https://github.com/dotnet/symstore</Uri>
<Sha>1ff51a5afa61af820a14b3aa84b401d1a79bc783</Sha>
</Dependency>
<Dependency Name="Microsoft.Diagnostics.Runtime" Version="2.0.325901">
<Dependency Name="Microsoft.Diagnostics.Runtime" Version="2.0.327704">
<Uri>https://github.com/microsoft/clrmd</Uri>
<Sha>a64d9ac11086f28fbd4b2b2337c19be7826fbfa9</Sha>
<Sha>be891ed2cc2c8b98d9e0b531b513b75a4d4bfd88</Sha>
</Dependency>
<Dependency Name="Microsoft.Diagnostics.Runtime.Utilities" Version="2.0.325901">
<Uri>https://github.com/microsoft/clrmd</Uri>
Expand Down
3 changes: 1 addition & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@
<MicrosoftWin32PrimitivesVersion>4.3.0</MicrosoftWin32PrimitivesVersion>
<!-- Other libs -->
<MicrosoftBclAsyncInterfacesVersion>1.1.0</MicrosoftBclAsyncInterfacesVersion>
<MicrosoftDiagnosticsRuntimeVersion>2.0.325901</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiagnosticsRuntimeUtilitiesVersion>2.0.325901</MicrosoftDiagnosticsRuntimeUtilitiesVersion>
<MicrosoftDiagnosticsRuntimeVersion>2.1.330601</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiaSymReaderNativePackageVersion>16.9.0-beta1.21055.5</MicrosoftDiaSymReaderNativePackageVersion>
<MicrosoftDiagnosticsTracingTraceEventVersion>2.0.64</MicrosoftDiagnosticsTracingTraceEventVersion>
<MicrosoftExtensionsLoggingVersion>2.1.1</MicrosoftExtensionsLoggingVersion>
Expand Down
206 changes: 206 additions & 0 deletions src/Microsoft.Diagnostics.DebugServices.Implementation/DataReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Microsoft.Diagnostics.DebugServices.Implementation
{
/// <summary>
/// ClrMD runtime service implementation
/// </summary>
internal class DataReader : IDataReader
{
private readonly ITarget _target;
private IEnumerable<ModuleInfo> _modules;
private IModuleService _moduleService;
private IThreadService _threadService;
private IMemoryService _memoryService;

public DataReader(ITarget target)
{
_target = target;
target.OnFlushEvent.Register(() => _modules = null);
}

#region IDataReader

string IDataReader.DisplayName => "";

bool IDataReader.IsThreadSafe => false;

OSPlatform IDataReader.TargetPlatform => _target.OperatingSystem;

Architecture IDataReader.Architecture => _target.Architecture;

int IDataReader.ProcessId => unchecked((int)_target.ProcessId.GetValueOrDefault());

IEnumerable<ModuleInfo> IDataReader.EnumerateModules() => _modules ??= ModuleService.EnumerateModules().Select((module) => new DataReaderModule(module)).ToList();

bool IDataReader.GetThreadContext(uint threadId, uint contextFlags, Span<byte> context)
{
try
{
byte[] registerContext = ThreadService.GetThreadFromId(threadId).GetThreadContext();
context = new Span<byte>(registerContext);
return true;
}
catch (DiagnosticsException ex)
{
Trace.TraceError($"GetThreadContext: {threadId} exception {ex.Message}");
}
return false;
}

void IDataReader.FlushCachedData()
{
}

#endregion

#region IMemoryReader

int IMemoryReader.PointerSize => MemoryService.PointerSize;

int IMemoryReader.Read(ulong address, Span<byte> buffer)
{
MemoryService.ReadMemory(address, buffer, out int bytesRead);
return bytesRead;
}

bool IMemoryReader.Read<T>(ulong address, out T value)
{
Span<byte> buffer = stackalloc byte[Marshal.SizeOf<T>()];
if (((IMemoryReader)this).Read(address, buffer) == buffer.Length)
{
value = Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(buffer));
return true;
}
value = default;
return false;
}

T IMemoryReader.Read<T>(ulong address)
{
((IMemoryReader)this).Read(address, out T result);
return result;
}

bool IMemoryReader.ReadPointer(ulong address, out ulong value)
{
return MemoryService.ReadPointer(address, out value);
}

ulong IMemoryReader.ReadPointer(ulong address)
{
MemoryService.ReadPointer(address, out ulong value);
return value;
}

#endregion

private IModuleService ModuleService => _moduleService ??= _target.Services.GetService<IModuleService>();

private IMemoryService MemoryService => _memoryService ??= _target.Services.GetService<IMemoryService>();

private IThreadService ThreadService => _threadService ??= _target.Services.GetService<IThreadService>();

private class DataReaderModule : ModuleInfo
{
private readonly IModule _module;

public DataReaderModule(IModule module)
: base(module.ImageBase, module.FileName)
{
_module = module;
}

public override long ImageSize => unchecked((long)_module.ImageSize);

public override int IndexFileSize => unchecked((int)_module.IndexFileSize.GetValueOrDefault(0));

public override int IndexTimeStamp => unchecked((int)_module.IndexTimeStamp.GetValueOrDefault(0));

public override Version Version
{
get
{
try
{
return _module.GetVersionData() ?? Utilities.EmptyVersion;
}
catch (DiagnosticsException ex)
{
Trace.TraceError($"ModuleInfo.Version: {_module.ImageBase:X16} exception {ex.Message}");
}
return Utilities.EmptyVersion;
}
}

public override ImmutableArray<byte> BuildId
{
get
{
try
{
return _module.BuildId;
}
catch (DiagnosticsException ex)
{
Trace.TraceError($"ModuleInfo.BuildId: {_module.ImageBase:X16} exception {ex.Message}");
}
return ImmutableArray<byte>.Empty;
}
}

public override PdbInfo Pdb
{
get
{
try
{
PdbFileInfo pdbFileInfo = _module.GetPdbFileInfos().Where((pdbFileInfo) => pdbFileInfo.IsPortable).LastOrDefault();
if (pdbFileInfo is null)
{
pdbFileInfo = _module.GetPdbFileInfos().LastOrDefault();
if (pdbFileInfo is null)
{
return default;
}
}
return new PdbInfo(pdbFileInfo.Path, pdbFileInfo.Guid, pdbFileInfo.Revision);
}
catch (DiagnosticsException ex)
{
Trace.TraceError($"ModuleInfo.Pdb: {_module.ImageBase:X16} exception {ex.Message}");
}
return default;
}
}

public override bool IsManaged => _module.IsManaged;

public override ulong GetExportSymbolAddress(string symbol)
{
var exportSymbols = _module.Services.GetService<IExportSymbols>();
if (exportSymbols is not null)
{
if (exportSymbols.TryGetSymbolAddress(symbol, out ulong offset))
{
return offset;
}
}
return 0;
}

public override IResourceNode ResourceRoot => base.ResourceRoot;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
// 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.Utilities;
using Microsoft.FileFormats;
using Microsoft.FileFormats.ELF;
using Microsoft.FileFormats.MachO;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.

using Microsoft.Diagnostics.Runtime;
using Microsoft.Diagnostics.Runtime.Utilities;
using Microsoft.FileFormats;
using Microsoft.FileFormats.PE;
using System;
Expand Down
38 changes: 14 additions & 24 deletions src/Microsoft.Diagnostics.DebugServices.Implementation/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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.Utilities;
using Microsoft.Diagnostics.Runtime;
using Microsoft.FileFormats;
using Microsoft.FileFormats.ELF;
using Microsoft.FileFormats.MachO;
Expand Down Expand Up @@ -197,7 +197,7 @@ public string GetSymbolFileName()
{
if (InitializeValue(Flags.InitializeSymbolFileName))
{
if (Target.OperatingSystem == OSPlatform.Linux)
if (ImageSize > 0 && Target.OperatingSystem == OSPlatform.Linux)
{
try
{
Expand All @@ -216,8 +216,8 @@ public string GetSymbolFileName()
(ex is InvalidVirtualAddressException ||
ex is ArgumentOutOfRangeException ||
ex is IndexOutOfRangeException ||
ex is OverflowException ||
mikem8361 marked this conversation as resolved.
Show resolved Hide resolved
ex is BadInputFormatException)

{
Trace.TraceWarning("ELF .gnu_debuglink section in {0}: {1}", this, ex.Message);
}
Expand All @@ -226,7 +226,7 @@ ex is IndexOutOfRangeException ||
return _symbolFileName;
}

public abstract VersionData GetVersionData();
public abstract Version GetVersionData();

public abstract string GetVersionString();

Expand Down Expand Up @@ -254,24 +254,15 @@ bool IExportSymbols.TryGetSymbolAddress(string name, out ulong address)
}
else if (Target.OperatingSystem == OSPlatform.Linux)
{
try
if (ImageSize > 0)
{
Stream stream = ModuleService.MemoryService.CreateMemoryStream(ImageBase, ImageSize);
ElfFile elfFile = new(stream, position: ImageBase, leaveOpen: false, isVirtual: true);
if (elfFile.Header.IsValid)
ModuleInfo module = ModuleInfo.TryCreate(Target.Services.GetService<DataReader>(), ImageBase, FileName);
if (module is not null)
{
if (elfFile.TryGetExportSymbol(name, out ulong offset))
{
address = ImageBase + offset;
return true;
}
address = 0;
return false;
address = module.GetExportSymbolAddress(name);
return address != 0;
}
}
catch (InvalidDataException)
{
}
}
return TryGetSymbolAddressInner(name, out address);
}
Expand All @@ -284,9 +275,9 @@ protected virtual bool TryGetSymbolAddressInner(string name, out ulong address)

#endregion

protected VersionData GetVersion()
protected Version GetVersionInner()
{
VersionData versionData = null;
Version version = null;

PEFile peFile = GetPEInfo();
if (peFile != null)
Expand All @@ -296,7 +287,7 @@ protected VersionData GetVersion()
VsFixedFileInfo fileInfo = peFile.VersionInfo;
if (fileInfo != null)
{
versionData = fileInfo.ToVersionData();
version = fileInfo.ToVersion();
}
}
catch (Exception ex) when (ex is InvalidVirtualAddressException || ex is BadInputFormatException)
Expand Down Expand Up @@ -325,8 +316,7 @@ protected VersionData GetVersion()
string versionToParse = versionString.Substring(0, spaceIndex);
try
{
Version version = System.Version.Parse(versionToParse);
versionData = new VersionData(version.Major, version.Minor, version.Build, version.Revision);
version = Version.Parse(versionToParse);
}
catch (ArgumentException ex)
{
Expand All @@ -336,7 +326,7 @@ protected VersionData GetVersion()
}
}

return versionData;
return version;
}

protected PEFile GetPEInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ internal PEFile GetPEInfo(ulong address, ulong size, out IEnumerable<PdbFileInfo
moduleFlags &= ~(Module.Flags.IsPEImage | Module.Flags.IsManaged | Module.Flags.IsLoadedLayout | Module.Flags.IsFileLayout);

// None of the modules that lldb (on either Linux/MacOS) provides are PEs
if (Target.Host.HostType != HostType.Lldb)
if (size > 0 && Target.Host.HostType != HostType.Lldb)
{
// First try getting the PE info as loaded layout (native Windows DLLs and most managed PEs).
peFile = GetPEInfo(isVirtual: true, address, size, out List<PdbFileInfo> pdbs, out Module.Flags flags);
Expand Down Expand Up @@ -367,7 +367,7 @@ protected string GetVersionString(IModule module)
}
else
{
Trace.TraceError($"GetVersionString: unsupported module {module} or platform {Target.OperatingSystem}");
Trace.TraceError($"GetVersionString: unsupported module {module} on platform {Target.OperatingSystem}");
}
}
}
Expand Down
Loading