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

[cdac] Implement ISOSDacInterface::GetModule and IXCLRDataModule::GetFileName #109133

Merged
merged 15 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
9 changes: 9 additions & 0 deletions docs/design/datacontracts/Loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ModuleHandle GetModuleHandle(TargetPointer module);
TargetPointer GetAssembly(ModuleHandle handle);
ModuleFlags GetFlags(ModuleHandle handle);
string GetPath(ModuleHandle handle);
string GetFileName(ModuleHandle handle);
TargetPointer GetLoaderAllocator(ModuleHandle handle);
TargetPointer GetThunkHeap(ModuleHandle handle);
TargetPointer GetILBase(ModuleHandle handle);
Expand All @@ -52,6 +53,7 @@ Data descriptors used:
| `Module` | `LoaderAllocator` | LoaderAllocator of the Module |
| `Module` | `ThunkHeap` | Pointer to the thunk heap |
| `Module` | `Path` | Path of the Module (UTF-16, null-terminated) |
| `Module` | `FileName` | File name of the Module (UTF-16, null-terminated) |
| `Module` | `FieldDefToDescMap` | Mapping table |
| `Module` | `ManifestModuleReferencesMap` | Mapping table |
| `Module` | `MemberRefToDescMap` | Mapping table |
Expand Down Expand Up @@ -86,6 +88,13 @@ string GetPath(ModuleHandle handle)
return new string(path);
}

string GetFileName(ModuleHandle handle)
{
TargetPointer fileNameStart = target.ReadPointer(handle.Address + /* Module::FileName offset */);
char[] fileName = // Read<char> from target starting at fileNameStart until null terminator
return new string(fileName);
}

TargetPointer GetLoaderAllocator(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */);
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,12 @@ CDAC_TYPE_BEGIN(Module)
CDAC_TYPE_INDETERMINATE(Module)
CDAC_TYPE_FIELD(Module, /*pointer*/, Assembly, cdac_data<Module>::Assembly)
CDAC_TYPE_FIELD(Module, /*pointer*/, Base, cdac_data<Module>::Base)
CDAC_TYPE_FIELD(Module, /*pointer*/, Flags, cdac_data<Module>::Flags)
CDAC_TYPE_FIELD(Module, /*uint32*/, Flags, cdac_data<Module>::Flags)
CDAC_TYPE_FIELD(Module, /*pointer*/, LoaderAllocator, cdac_data<Module>::LoaderAllocator)
CDAC_TYPE_FIELD(Module, /*pointer*/, ThunkHeap, cdac_data<Module>::ThunkHeap)
CDAC_TYPE_FIELD(Module, /*pointer*/, DynamicMetadata, cdac_data<Module>::DynamicMetadata)
CDAC_TYPE_FIELD(Module, /*pointer*/, Path, cdac_data<Module>::Path)
CDAC_TYPE_FIELD(Module, /*pointer*/, FileName, cdac_data<Module>::FileName)

CDAC_TYPE_FIELD(Module, /*pointer*/, FieldDefToDescMap, cdac_data<Module>::FieldDefToDescMap)
CDAC_TYPE_FIELD(Module, /*pointer*/, ManifestModuleReferencesMap, cdac_data<Module>::ManifestModuleReferencesMap)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
m_loaderAllocator = GetAssembly()->GetLoaderAllocator();
m_pSimpleName = m_pPEAssembly->GetSimpleName();
m_path = m_pPEAssembly->GetPath().GetUnicode();
m_fileName = m_pPEAssembly->GetModuleFileNameHint();
_ASSERTE(m_path != NULL);
m_baseAddress = m_pPEAssembly->HasLoadedPEImage() ? m_pPEAssembly->GetLoadedLayout()->GetBase() : NULL;
if (m_pPEAssembly->IsReflectionEmit())
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,9 @@ class Module : public ModuleBase
VPTR_VTABLE_CLASS(Module, ModuleBase)

private:
PTR_CUTF8 m_pSimpleName; // Cached simple name for better performance and easier diagnostics
const WCHAR* m_path; // Cached path for easier diagnostics
PTR_CUTF8 m_pSimpleName; // Cached simple name for better performance and easier diagnostics
const WCHAR* m_path; // Cached path for easier diagnostics
const WCHAR* m_fileName; // Cached file name for easier diagnostics

PTR_PEAssembly m_pPEAssembly;
PTR_VOID m_baseAddress; // Cached base address for easier diagnostics
Expand Down Expand Up @@ -1647,6 +1648,7 @@ struct cdac_data<Module>
static constexpr size_t ThunkHeap = offsetof(Module, m_pThunkHeap);
static constexpr size_t DynamicMetadata = offsetof(Module, m_pDynamicMetadata);
static constexpr size_t Path = offsetof(Module, m_path);
static constexpr size_t FileName = offsetof(Module, m_fileName);

// Lookup map pointers
static constexpr size_t FieldDefToDescMap = offsetof(Module, m_FieldDefToDescMap);
Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/vm/peassembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ class PEAssembly final
const SString& GetPath();
const SString& GetIdentityPath();

#ifdef DACCESS_COMPILE
// This is the metadata module name. Used as a hint as file name.
// This is the module file name. Used as a hint as file name.
// For assemblies loaded from a path or single-file bundle, this is the file name portion of the path
// For assemblies loaded from memory, this is the module file name from metadata
// For reflection emitted assemblies, this is an empty string
const SString &GetModuleFileNameHint();
#endif // DACCESS_COMPILE

LPCWSTR GetPathForErrorMessages();

Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/vm/peassembly.inl
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ inline const SString& PEAssembly::GetIdentityPath()
return m_PEImage->GetPath();
}

#ifdef DACCESS_COMPILE
inline const SString &PEAssembly::GetModuleFileNameHint()
{
CONTRACTL
Expand All @@ -201,7 +200,6 @@ inline const SString &PEAssembly::GetModuleFileNameHint()
else
return m_PEImage->GetModuleFileNameHintForDAC();
}
#endif // DACCESS_COMPILE

#ifdef LOGGING
inline LPCUTF8 PEAssembly::GetDebugName()
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/peimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,11 @@ void PEImage::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
// these necessary fields enumerated no matter what.
m_path.EnumMemoryRegions(flags);

// We always want this field in mini/triage/heap dumps.
// SString skips enumeration for triage dumps, but we always want this field, so we specify
// CLRDATA_ENUM_MEM_DEFAULT as the flags. This value is used in cases where we either can't
// use the full path (triage dumps) or don't have a path (in-memory assembly)
m_sModuleFileNameHintUsedByDac.EnumMemoryRegions(CLRDATA_ENUM_MEM_DEFAULT);


EX_TRY
{
if (HasLoadedLayout() && HasNTHeaders() && HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG))
Expand Down
12 changes: 5 additions & 7 deletions src/coreclr/vm/peimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ class PEImage final
void SetModuleFileNameHintForDAC();
#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
const SString &GetModuleFileNameHintForDAC();
#endif
const SString &GetModuleFileNameHintForDAC();

private:
#ifndef DACCESS_COMPILE
Expand Down Expand Up @@ -302,12 +302,10 @@ class PEImage final
DWORD m_dwPEKind;
DWORD m_dwMachine;

// This variable will have the data of module name.
// It is only used by DAC to remap fusion loaded modules back to
// disk IL. This really is a workaround. The real fix is for fusion loader
// hook (public API on hosting) to take an additional file name hint.
// We are piggy backing on the fact that module name is the same as file name!!!
SString m_sModuleFileNameHintUsedByDac; // This is only used by DAC
// This only used by DAC
// For assemblies loaded from a path or single-file bundle, this is the file name portion of the path
// For assemblies loaded from memory, this is the module file name from metadata
SString m_sModuleFileNameHintUsedByDac;

enum
{
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/vm/peimage.inl
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,12 @@ inline void PEImage::SetModuleFileNameHintForDAC()
}
}

#ifdef DACCESS_COMPILE
inline const SString &PEImage::GetModuleFileNameHintForDAC()
{
LIMITED_METHOD_CONTRACT;

return m_sModuleFileNameHintUsedByDac;
}
#endif



inline BOOL PEImage::IsFile()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ internal interface ILoader : IContract
public virtual TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException();
public virtual ModuleFlags GetFlags(ModuleHandle handle) => throw new NotImplementedException();
public virtual string GetPath(ModuleHandle handle) => throw new NotImplementedException();
public virtual string GetFileName(ModuleHandle handle) => throw new NotImplementedException();

public virtual TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException();
public virtual TargetPointer GetThunkHeap(ModuleHandle handle) => throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,17 @@ ModuleFlags ILoader.GetFlags(ModuleHandle handle)
string ILoader.GetPath(ModuleHandle handle)
{
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
return _target.ReadUtf16String(module.Path);
return module.Path != TargetPointer.Null
? _target.ReadUtf16String(module.Path)
: string.Empty;
}

string ILoader.GetFileName(ModuleHandle handle)
{
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
return module.FileName != TargetPointer.Null
? _target.ReadUtf16String(module.FileName)
: string.Empty;
}

TargetPointer ILoader.GetLoaderAllocator(ModuleHandle handle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public Module(Target target, TargetPointer address)
ThunkHeap = target.ReadPointer(address + (ulong)type.Fields[nameof(ThunkHeap)].Offset);
DynamicMetadata = target.ReadPointer(address + (ulong)type.Fields[nameof(DynamicMetadata)].Offset);
Path = target.ReadPointer(address + (ulong)type.Fields[nameof(Path)].Offset);
FileName = target.ReadPointer(address + (ulong)type.Fields[nameof(FileName)].Offset);

FieldDefToDescMap = address + (ulong)type.Fields[nameof(FieldDefToDescMap)].Offset;
ManifestModuleReferencesMap = address + (ulong)type.Fields[nameof(ManifestModuleReferencesMap)].Offset;
Expand All @@ -41,6 +42,7 @@ public Module(Target target, TargetPointer address)
public TargetPointer ThunkHeap { get; init; }
public TargetPointer DynamicMetadata { get; init; }
public TargetPointer Path { get; init; }
public TargetPointer FileName { get; init; }

public TargetPointer FieldDefToDescMap { get; init; }
public TargetPointer ManifestModuleReferencesMap { get; init; }
Expand Down
Loading
Loading