{
get
{
- GetPEInfo();
- return (_flags & Flags.IsPEImage) != 0;
+ // For Windows targets, we can always assume that all the modules are PEs.
+ if (Target.OperatingSystem == OSPlatform.Windows)
+ {
+ return true;
+ }
+ else
+ {
+ GetPEInfo();
+ return (_flags & Flags.IsPEImage) != 0;
+ }
}
}
{
if (Target.OperatingSystem == OSPlatform.Windows)
{
- Stream stream = Target.Services.GetService<IMemoryService>().CreateMemoryStream(ImageBase, ImageSize);
+ Stream stream = ModuleService.MemoryService.CreateMemoryStream(ImageBase, ImageSize);
PEFile image = new(new StreamAddressSpace(stream), isDataSourceVirtualAddressSpace: true);
if (image.IsValid())
{
{
try
{
- Stream stream = Target.Services.GetService<IMemoryService>().CreateMemoryStream(ImageBase, ImageSize);
+ Stream stream = ModuleService.MemoryService.CreateMemoryStream(ImageBase, ImageSize);
ElfFile elfFile = new(stream, position: ImageBase, leaveOpen: false, isVirtual: true);
if (elfFile.Header.IsValid)
{
const uint VmProtWrite = 0x02;
internal protected readonly ITarget Target;
+ internal protected IMemoryService RawMemoryService;
private IMemoryService _memoryService;
private ISymbolService _symbolService;
private ReadVirtualCache _versionCache;
private static readonly byte[] s_versionString = Encoding.ASCII.GetBytes("@(#)Version ");
private static readonly int s_versionLength = s_versionString.Length;
- public ModuleService(ITarget target)
+ public ModuleService(ITarget target, IMemoryService rawMemoryService)
{
Debug.Assert(target != null);
Target = target;
+ RawMemoryService = rawMemoryService;
target.OnFlushEvent.Register(() => {
_versionCache?.Clear();
/// <returns>module or null</returns>
IModule IModuleService.GetModuleFromAddress(ulong address)
{
- Debug.Assert((address & ~MemoryService.SignExtensionMask()) == 0);
+ Debug.Assert((address & ~RawMemoryService.SignExtensionMask()) == 0);
IModule[] modules = GetSortedModules();
int min = 0, max = modules.Length - 1;
IModule module = modules[mid];
ulong start = module.ImageBase;
- Debug.Assert((start & ~MemoryService.SignExtensionMask()) == 0);
+ Debug.Assert((start & ~RawMemoryService.SignExtensionMask()) == 0);
ulong end = start + module.ImageSize;
if (address >= start && address < end) {
/// <returns>PEImage instance or null</returns>
private PEImage GetPEInfo(bool isVirtual, ulong address, ulong size, ref PdbFileInfo pdbFileInfo, ref Module.Flags flags)
{
- Stream stream = MemoryService.CreateMemoryStream(address, size);
+ Stream stream = RawMemoryService.CreateMemoryStream(address, size);
try
{
stream.Position = 0;
/// <returns>build id or null</returns>
internal byte[] GetBuildId(ulong address)
{
- Stream stream = MemoryService.CreateMemoryStream();
+ Stream stream = RawMemoryService.CreateMemoryStream();
byte[] buildId = null;
try
{
/// <returns>version string or null</returns>
protected string GetVersionString(ulong address)
{
- Stream stream = MemoryService.CreateMemoryStream();
+ Stream stream = RawMemoryService.CreateMemoryStream();
try
{
if (Target.OperatingSystem == OSPlatform.Linux)
{
foreach (ELFProgramHeader programHeader in elfFile.Segments.Select((segment) => segment.Header))
{
- uint flags = MemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
+ uint flags = RawMemoryService.PointerSize == 8 ? programHeader.Flags : programHeader.Flags32;
if (programHeader.Type == ELFProgramHeaderType.Load &&
(flags & (uint)ELFProgramHeaderAttributes.Writable) != 0)
{
byte[] buffer = new byte[s_versionString.Length];
if (_versionCache == null) {
- _versionCache = new ReadVirtualCache(MemoryService);
+ // We use the possibly mapped memory service to find the version string in case it isn't in the dump.
+ _versionCache = new ReadVirtualCache(Target.Services.GetService<IMemoryService>());
}
_versionCache.Clear();
else {
return string.Equals(Path.GetFileName(module.FileName), moduleName);
}
- }
+ }
- protected IMemoryService MemoryService => _memoryService ??= Target.Services.GetService<IMemoryService>();
+ internal protected IMemoryService MemoryService => _memoryService ??= Target.Services.GetService<IMemoryService>();
- protected ISymbolService SymbolService => _symbolService ??= Target.Services.GetService<ISymbolService>();
+ internal protected ISymbolService SymbolService => _symbolService ??= Target.Services.GetService<ISymbolService>();
/// <summary>
/// Search memory helper class
{
ImmutableArray<byte> buildId = _moduleService._dataReader.GetBuildId(ImageBase);
// If the data reader can't get the build id, it returns a empty (instead of default) immutable array.
- _buildId = buildId.IsEmpty ? base.BuildId : buildId;
+ _buildId = buildId.IsDefaultOrEmpty ? base.BuildId : buildId;
}
return _buildId;
}
private readonly IDataReader _dataReader;
- public ModuleServiceFromDataReader(ITarget target, IDataReader dataReader)
- : base(target)
+ public ModuleServiceFromDataReader(ITarget target, IMemoryService rawMemoryService, IDataReader dataReader)
+ : base(target, rawMemoryService)
{
_dataReader = dataReader;
}
}
// Add the thread, memory, and module services
+ IMemoryService rawMemoryService = new MemoryServiceFromDataReader(_dataReader);
ServiceProvider.AddServiceFactory<IThreadService>(() => new ThreadServiceFromDataReader(this, _dataReader));
- ServiceProvider.AddServiceFactory<IModuleService>(() => new ModuleServiceFromDataReader(this, _dataReader));
+ ServiceProvider.AddServiceFactory<IModuleService>(() => new ModuleServiceFromDataReader(this, rawMemoryService, _dataReader));
ServiceProvider.AddServiceFactory<IMemoryService>(() => {
- IMemoryService memoryService = new MemoryServiceFromDataReader(_dataReader);
+ IMemoryService memoryService = rawMemoryService;
if (IsDump)
{
memoryService = new ImageMappingMemoryService(this, memoryService);
IntPtr self)
{
Trace.TraceInformation("HostServices.DestroyTarget #{0}", _target != null ? _target.Id : "<none>");
- if (_target != null)
+ try
+ {
+ if (_target != null)
+ {
+ DestroyTarget(_target);
+ }
+ }
+ catch (Exception ex)
{
- DestroyTarget(_target);
+ Trace.TraceError(ex.ToString());
}
}
IntPtr self)
{
Trace.TraceInformation("HostServices.Uninitialize");
- DestroyTarget(self);
-
- if (DebuggerServices != null)
+ try
{
- DebuggerServices.Release();
- DebuggerServices = null;
- }
+ DestroyTarget(self);
+
+ if (DebuggerServices != null)
+ {
+ DebuggerServices.Release();
+ DebuggerServices = null;
+ }
- // Send shutdown event on exit
- OnShutdownEvent.Fire();
+ // Send shutdown event on exit
+ OnShutdownEvent.Fire();
- // Release the host services wrapper
- Release();
+ // Release the host services wrapper
+ Release();
- // Clear HostService instance
- Instance = null;
+ // Clear HostService instance
+ Instance = null;
+ }
+ catch (Exception ex)
+ {
+ Trace.TraceError(ex.ToString());
+ }
}
#endregion
private readonly DebuggerServices _debuggerServices;
- internal ModuleServiceFromDebuggerServices(ITarget target, DebuggerServices debuggerServices)
- : base(target)
+ internal ModuleServiceFromDebuggerServices(ITarget target, IMemoryService rawMemoryService, DebuggerServices debuggerServices)
+ : base(target, rawMemoryService)
{
Debug.Assert(debuggerServices != null);
_debuggerServices = debuggerServices;
}
// Add the thread, memory, and module services
- ServiceProvider.AddServiceFactory<IModuleService>(() => new ModuleServiceFromDebuggerServices(this, debuggerServices));
+ IMemoryService rawMemoryService = new MemoryServiceFromDebuggerServices(this, debuggerServices);
+ ServiceProvider.AddServiceFactory<IModuleService>(() => new ModuleServiceFromDebuggerServices(this, rawMemoryService, debuggerServices));
ServiceProvider.AddServiceFactory<IThreadService>(() => new ThreadServiceFromDebuggerServices(this, debuggerServices));
ServiceProvider.AddServiceFactory<IMemoryService>(() => {
- IMemoryService memoryService = new MemoryServiceFromDebuggerServices(this, debuggerServices);
Debug.Assert(Host.HostType != HostType.DotnetDump);
+ IMemoryService memoryService = rawMemoryService;
if (IsDump && Host.HostType == HostType.Lldb)
{
// This is a special memory service that maps the managed assemblies' metadata into the address
// space. The lldb debugger returns zero's (instead of failing the memory read) for missing pages
// in core dumps that older (< 5.0) createdumps generate so it needs this special metadata mapping
// memory service. dotnet-dump needs this logic for clrstack -i (uses ICorDebug data targets).
- memoryService = new MetadataMappingMemoryService(this, memoryService);
+ return new MetadataMappingMemoryService(this, memoryService);
}
return memoryService;
});