Skip to content

Commit 2d3bf38

Browse files
rcj1Copilot
andauthored
Adding GetAppDomainName cDAC API (#117837)
* Adding GetAppDomainName cDAC API Co-authored-by: Copilot <[email protected]>
1 parent 27cc30f commit 2d3bf38

File tree

7 files changed

+88
-7
lines changed

7 files changed

+88
-7
lines changed

docs/design/datacontracts/Loader.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ ModuleHandle GetModuleHandleFromModulePtr(TargetPointer module);
5656
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer);
5757
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
5858
TargetPointer GetRootAssembly();
59+
string GetAppDomainFriendlyName();
5960
TargetPointer GetModule(ModuleHandle handle);
6061
TargetPointer GetAssembly(ModuleHandle handle);
6162
TargetPointer GetPEAssembly(ModuleHandle handle);
@@ -116,6 +117,7 @@ TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer);
116117
| `CGrowableSymbolStream` | `Size` | Size of the raw symbol stream buffer |
117118
| `AppDomain` | `RootAssembly` | Pointer to the root assembly |
118119
| `AppDomain` | `DomainAssemblyList` | ArrayListBase of assemblies in the AppDomain |
120+
| `AppDomain` | `FriendlyName` | Friendly name of the AppDomain |
119121
| `LoaderAllocator` | `ReferenceCount` | Reference count of LoaderAllocator |
120122
| `LoaderAllocator` | `HighFrequencyHeap` | High-frequency heap of LoaderAllocator |
121123
| `LoaderAllocator` | `LowFrequencyHeap` | Low-frequency heap of LoaderAllocator |
@@ -270,6 +272,15 @@ TargetPointer GetRootAssembly()
270272
return appDomain.RootAssembly;
271273
}
272274

275+
string ILoader.GetAppDomainFriendlyName()
276+
{
277+
TargetPointer appDomainPointer = target.ReadGlobalPointer(Constants.Globals.AppDomain);
278+
TargetPointer appDomain = target.ReadPointer(appDomainPointer)
279+
TargetPointer pathStart = appDomain + /* AppDomain::FriendlyName offset */;
280+
char[] name = // Read<char> from target starting at pathStart until null terminator
281+
return new string(name);
282+
}
283+
273284
TargetPointer ILoader.GetModule(ModuleHandle handle)
274285
{
275286
return handle.Address;
@@ -395,20 +406,20 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar
395406
uint index = rid;
396407
// have to read lookupMap an extra time upfront because only the first map
397408
// has valid supportedFlagsMask
398-
TargetNUInt supportedFlagsMask = _target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
409+
TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
399410
do
400411
{
401-
if (index < _target.Read<uint>(table + /*ModuleLookupMap::Count*/))
412+
if (index < target.Read<uint>(table + /*ModuleLookupMap::Count*/))
402413
{
403-
TargetPointer entryAddress = _target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * _target.PointerSize);
404-
TargetPointer rawValue = _target.ReadPointer(entryAddress);
414+
TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize);
415+
TargetPointer rawValue = target.ReadPointer(entryAddress);
405416
flags = rawValue & supportedFlagsMask;
406417
return rawValue & ~(supportedFlagsMask.Value);
407418
}
408419
else
409420
{
410-
table = _target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
411-
index -= _target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
421+
table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
422+
index -= target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
412423
}
413424
} while (table != TargetPointer.Null);
414425
return TargetPointer.Null;

src/coreclr/debug/runtimeinfo/datadescriptor.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ CDAC_TYPE_BEGIN(AppDomain)
295295
CDAC_TYPE_INDETERMINATE(AppDomain)
296296
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, RootAssembly, cdac_data<AppDomain>::RootAssembly)
297297
CDAC_TYPE_FIELD(AppDomain, /*DomainAssemblyList*/, DomainAssemblyList, cdac_data<AppDomain>::DomainAssemblyList)
298+
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, FriendlyName, cdac_data<AppDomain>::FriendlyName)
298299
CDAC_TYPE_END(AppDomain)
299300

300301
CDAC_TYPE_BEGIN(SystemDomain)

src/coreclr/vm/appdomain.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,7 @@ struct cdac_data<AppDomain>
15711571
{
15721572
static constexpr size_t RootAssembly = offsetof(AppDomain, m_pRootAssembly);
15731573
static constexpr size_t DomainAssemblyList = offsetof(AppDomain, m_Assemblies) + offsetof(AppDomain::DomainAssemblyList, m_array);
1574+
static constexpr size_t FriendlyName = offsetof(AppDomain, m_friendlyName);
15741575
};
15751576

15761577
typedef DPTR(class SystemDomain) PTR_SystemDomain;

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public interface ILoader : IContract
7979
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer) => throw new NotImplementedException();
8080
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) => throw new NotImplementedException();
8181
TargetPointer GetRootAssembly() => throw new NotImplementedException();
82+
string GetAppDomainFriendlyName() => throw new NotImplementedException();
8283
TargetPointer GetModule(ModuleHandle handle) => throw new NotImplementedException();
8384
TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException();
8485
TargetPointer GetPEAssembly(ModuleHandle handle) => throw new NotImplementedException();

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ TargetPointer ILoader.GetRootAssembly()
139139
Data.AppDomain appDomain = _target.ProcessedData.GetOrAdd<Data.AppDomain>(_target.ReadPointer(appDomainPointer));
140140
return appDomain.RootAssembly;
141141
}
142+
143+
string ILoader.GetAppDomainFriendlyName()
144+
{
145+
TargetPointer appDomainPointer = _target.ReadGlobalPointer(Constants.Globals.AppDomain);
146+
Data.AppDomain appDomain = _target.ProcessedData.GetOrAdd<Data.AppDomain>(_target.ReadPointer(appDomainPointer));
147+
return appDomain.FriendlyName != TargetPointer.Null
148+
? _target.ReadUtf16String(appDomain.FriendlyName)
149+
: string.Empty;
150+
}
151+
142152
TargetPointer ILoader.GetModule(ModuleHandle handle)
143153
{
144154
return handle.Address;

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AppDomain.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ public AppDomain(Target target, TargetPointer address)
1414

1515
RootAssembly = target.ReadPointer(address + (ulong)type.Fields[nameof(RootAssembly)].Offset);
1616
DomainAssemblyList = address + (ulong)type.Fields[nameof(DomainAssemblyList)].Offset;
17+
FriendlyName = target.ReadPointer(address + (ulong)type.Fields[nameof(FriendlyName)].Offset);
1718
}
1819

1920
public TargetPointer RootAssembly { get; init; }
2021
public TargetPointer DomainAssemblyList { get; init; }
22+
public TargetPointer FriendlyName { get; init; }
2123
}

src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,62 @@ int ISOSDacInterface.GetAppDomainList(uint count, [In, MarshalUsing(CountElement
227227
return hr;
228228
}
229229
int ISOSDacInterface.GetAppDomainName(ClrDataAddress addr, uint count, char* name, uint* pNeeded)
230-
=> _legacyImpl is not null ? _legacyImpl.GetAppDomainName(addr, count, name, pNeeded) : HResults.E_NOTIMPL;
230+
{
231+
int hr = HResults.S_OK;
232+
try
233+
{
234+
ILoader loader = _target.Contracts.Loader;
235+
string friendlyName = loader.GetAppDomainFriendlyName();
236+
TargetPointer systemDomainPtr = _target.ReadGlobalPointer(Constants.Globals.SystemDomain);
237+
ClrDataAddress systemDomain = _target.ReadPointer(systemDomainPtr).ToClrDataAddress(_target);
238+
if (addr == systemDomain || friendlyName == string.Empty)
239+
{
240+
if (pNeeded is not null)
241+
{
242+
*pNeeded = 1;
243+
}
244+
if (name is not null && count > 0)
245+
{
246+
name[0] = '\0'; // Set the first character to null terminator
247+
}
248+
}
249+
else
250+
{
251+
if (pNeeded is not null)
252+
{
253+
*pNeeded = (uint)(friendlyName.Length + 1); // +1 for null terminator
254+
}
255+
256+
if (name is not null && count > 0)
257+
{
258+
OutputBufferHelpers.CopyStringToBuffer(name, count, pNeeded, friendlyName);
259+
}
260+
}
261+
}
262+
catch (System.Exception ex)
263+
{
264+
hr = ex.HResult;
265+
}
266+
#if DEBUG
267+
if (_legacyImpl is not null)
268+
{
269+
uint neededLocal;
270+
char[] nameLocal = new char[count];
271+
int hrLocal;
272+
fixed (char* ptr = nameLocal)
273+
{
274+
hrLocal = _legacyImpl.GetAppDomainName(addr, count, ptr, &neededLocal);
275+
}
276+
Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}");
277+
if (hr == HResults.S_OK)
278+
{
279+
Debug.Assert(pNeeded == null || *pNeeded == neededLocal);
280+
Debug.Assert(name == null || new ReadOnlySpan<char>(nameLocal, 0, (int)neededLocal - 1).SequenceEqual(new string(name)));
281+
}
282+
}
283+
#endif
284+
return hr;
285+
}
231286
int ISOSDacInterface.GetAppDomainStoreData(void* data)
232287
{
233288
DacpAppDomainStoreData* appDomainStoreData = (DacpAppDomainStoreData*)data;

0 commit comments

Comments
 (0)