Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
b98afa8
Implement GetThreadStoreData in cDAC
elinor-fung May 16, 2024
890f9c6
Add placeholder for getting thread data
elinor-fung May 17, 2024
41ba95c
Apply suggestions from code review
elinor-fung May 23, 2024
29214f0
WIP: Metadata contract
lambdageek May 14, 2024
8beced0
Merge remote-tracking branch 'elinor-fung/cdac-threadstore' into cdac…
lambdageek May 29, 2024
5213286
fix build
lambdageek May 29, 2024
622e01a
WIP: ValidateMethodTable
lambdageek May 29, 2024
e112416
DataCache.GetOrAdd
elinor-fung May 29, 2024
ae1eac9
wip
lambdageek May 30, 2024
79ea0d4
Merge remote-tracking branch 'elinor-fung/cdac-threadstore' into cdac…
lambdageek May 30, 2024
5c696da
checkpoint: ValidateWithPossibleAV
lambdageek May 30, 2024
6eaf80f
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek May 30, 2024
3a7808d
checkpoint EEClass from MethodTable
lambdageek May 31, 2024
66e5476
checkpoint: ValidateMethodTablePointer
lambdageek May 31, 2024
95914b8
cp: delegate from legacy dac
lambdageek May 31, 2024
2b8fda3
add Metadata to runtime contract descriptor
lambdageek Jun 11, 2024
5c7d2ac
checkpoint: more MethodTable fields
lambdageek Jun 12, 2024
7be5c60
checkpoint GetMethodTableData implemented
lambdageek Jun 13, 2024
30b7b26
checkpoint: same answer as legacy dac
lambdageek Jun 13, 2024
187bcbe
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 14, 2024
f0d1fcb
new flags for statics
lambdageek Jun 14, 2024
c53db36
fix GCC build
lambdageek Jun 14, 2024
b70bb1d
WIP: opaque MethodTableHandle
lambdageek Jun 17, 2024
a65fd50
Add contract accessors for MethodTableHandle
lambdageek Jun 18, 2024
6f844bf
fixup
lambdageek Jun 18, 2024
76e0384
simplify FreeObjectMethodTable handling
lambdageek Jun 18, 2024
cdb7543
cleanup
lambdageek Jun 18, 2024
78830ea
fixup
lambdageek Jun 18, 2024
fbbd45b
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 18, 2024
32665b2
[dac] Return canonical MethodTable instead of EEClass
lambdageek Jun 18, 2024
acf8436
Delete unreferenced MethodTable flags
lambdageek Jun 18, 2024
f246c86
add Metadata contract doc; fixups
lambdageek Jun 19, 2024
8409f3e
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 20, 2024
08d069a
rename DacpMethodTableData:klass field
lambdageek Jun 20, 2024
674655f
document GetMethodTableData string baseSize adjustment
lambdageek Jun 20, 2024
2ae4625
Apply suggestions from code review
lambdageek Jun 20, 2024
e18a2be
fix typo
lambdageek Jun 21, 2024
846e779
rename flag to ContainsGCPointers
lambdageek Jun 21, 2024
383af83
[vm] rename ContainsPointers flag to ContainsGCPointers
lambdageek Jun 21, 2024
0f8c7f1
code style suggestions from code review
lambdageek Jun 21, 2024
7a337c1
BUGFIX: read DwFlags2 from the correct offset
lambdageek Jun 21, 2024
a7c8158
hide utility methods
lambdageek Jun 21, 2024
f4a3493
remove EEClass_1 struct
lambdageek Jun 21, 2024
10624c7
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 21, 2024
65cc531
rename data descriptor members to remove prefixes
lambdageek Jun 21, 2024
d526087
cleanup the contract docs
lambdageek Jun 21, 2024
0a4112e
remove hungariant notation prefixes from data descriptors
lambdageek Jun 24, 2024
1071ca4
DAC: always set wNumVirtuals and wNumVtableSlots to 0
lambdageek Jun 25, 2024
6c5235c
Remove NumVirtuals and NumVtableSlots from Metadata.md
lambdageek Jun 27, 2024
95b728a
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jun 28, 2024
6573e14
"untrusted" -> "non-validated"
lambdageek Jun 28, 2024
8596892
merge fixup
lambdageek Jun 28, 2024
6eabf42
remove #if 0
lambdageek Jun 28, 2024
4d3200d
cleanup
lambdageek Jun 28, 2024
2e66740
pull test target helpers out
lambdageek Jun 28, 2024
8533148
Add one FreeObjectMethodTable unit test
lambdageek Jul 1, 2024
77cf405
clean up the test helpers a bit
lambdageek Jul 2, 2024
f9bce4c
validate that a mock system object is a valid method table
lambdageek Jul 2, 2024
3721992
code review feedback and more tests:
lambdageek Jul 2, 2024
1af7c80
Update src/coreclr/gc/env/gcenv.object.h
lambdageek Jul 2, 2024
993ae1d
Update src/native/managed/cdacreader/src/Contracts/Metadata_1.MethodT…
lambdageek Jul 2, 2024
f04d880
Address code review feedback
lambdageek Jul 2, 2024
76859d1
move non-validated MethodTable handling to a separate class
lambdageek Jul 2, 2024
a12a407
clear up ComponentSize contract spec and impl
lambdageek Jul 2, 2024
9cf4c5a
rename Metadata -> RuntimeTypeSystem
lambdageek Jul 3, 2024
1814848
add validation failure test; change validation to throw InvalidOperat…
lambdageek Jul 3, 2024
89f98a3
Merge remote-tracking branch 'origin/main' into cdac-wip
lambdageek Jul 3, 2024
a0989fa
Update src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_…
lambdageek Jul 3, 2024
617bf62
spellcheck
lambdageek Jul 3, 2024
815ff0d
Merge branch 'cdac-wip' of github.com:lambdageek/runtime into cdac-wip
lambdageek Jul 3, 2024
1ab4f08
Add a generic instance test
lambdageek Jul 3, 2024
ee3a362
add array instance test
lambdageek Jul 3, 2024
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
Prev Previous commit
Next Next commit
Add placeholder for getting thread data
  • Loading branch information
elinor-fung committed May 17, 2024
commit 890f9c6a6c3a73886dfe6c3e283d969cec92d422
2 changes: 1 addition & 1 deletion docs/design/datacontracts/Thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ ThreadData GetThreadData(TargetPointer threadPointer)
AllocContextLimit : thread.m_alloc_context.alloc_limit,
Frame : thread.m_pFrame,
TEB : thread.Has_m_pTEB ? thread.m_pTEB : TargetPointer.Null,
LastThreadObjectHandle : new DacGCHandle(thread.m_LastThrownObjectHandle),
LastThrownObjectHandle : new DacGCHandle(thread.m_LastThrownObjectHandle),
FirstNestedException : firstNestedException,
NextThread : ThreadListReader.GetHead.GetNext(threadPointer)
);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/daccess/dacimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,7 @@ class ClrDataAccess

HRESULT Initialize(void);

HRESULT GetThreadDataImpl(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData);
HRESULT GetThreadStoreDataImpl(struct DacpThreadStoreData *data);

BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
Expand Down
48 changes: 44 additions & 4 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,11 +761,52 @@ ClrDataAccess::GetHeapAllocData(unsigned int count, struct DacpGenerationAllocDa
return hr;
}

HRESULT
ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData)
HRESULT ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData* threadData)
{
SOSDacEnter();

if (m_cdacSos != NULL)
{
hr = m_cdacSos->GetThreadData(threadAddr, threadData);
if (FAILED(hr))
{
hr = GetThreadDataImpl(threadAddr, threadData);
}
#ifdef _DEBUG
else
{
DacpThreadData threadDataLocal;
HRESULT hrLocal = GetThreadDataImpl(threadAddr, &threadDataLocal);
_ASSERTE(hr == hrLocal);
_ASSERTE(threadData->corThreadId == threadDataLocal.corThreadId);
_ASSERTE(threadData->osThreadId == threadDataLocal.osThreadId);
_ASSERTE(threadData->state == threadDataLocal.state);
_ASSERTE(threadData->preemptiveGCDisabled == threadDataLocal.preemptiveGCDisabled);
_ASSERTE(threadData->allocContextPtr == threadDataLocal.allocContextPtr);
_ASSERTE(threadData->allocContextLimit == threadDataLocal.allocContextLimit);
_ASSERTE(threadData->context == threadDataLocal.context);
_ASSERTE(threadData->domain == threadDataLocal.domain);
_ASSERTE(threadData->pFrame == threadDataLocal.pFrame);
_ASSERTE(threadData->lockCount == threadDataLocal.lockCount);
_ASSERTE(threadData->firstNestedException == threadDataLocal.firstNestedException);
_ASSERTE(threadData->teb == threadDataLocal.teb);
_ASSERTE(threadData->fiberData == threadDataLocal.fiberData);
_ASSERTE(threadData->lastThrownObjectHandle == threadDataLocal.lastThrownObjectHandle);
_ASSERTE(threadData->nextThread == threadDataLocal.nextThread);;
}
#endif
}
else
{
hr = GetThreadDataImpl(threadAddr, threadData);
}

SOSDacLeave();
return hr;
}

HRESULT ClrDataAccess::GetThreadDataImpl(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *threadData)
{
// marshal the Thread object from the target
Thread* thread = PTR_Thread(TO_TADDR(threadAddr));

Expand Down Expand Up @@ -804,8 +845,7 @@ ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThreadData *
thread->m_ExceptionState.m_currentExInfo.m_pPrevNestedInfo);
#endif // FEATURE_EH_FUNCLETS

SOSDacLeave();
return hr;
return S_OK;
}

#ifdef FEATURE_REJIT
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ CDAC_TYPES_BEGIN()

CDAC_TYPE_BEGIN(Thread)
CDAC_TYPE_INDETERMINATE(Thread)
CDAC_TYPE_FIELD(Thread, /*uint32*/, Id, cdac_offsets<Thread>::Id)
CDAC_TYPE_FIELD(Thread, /*nuint*/, OSId, cdac_offsets<Thread>::OSId)
CDAC_TYPE_FIELD(Thread, GCHandle, GCHandle, cdac_offsets<Thread>::ExposedObject)
CDAC_TYPE_FIELD(Thread, GCHandle, LastThrownObject, cdac_offsets<Thread>::LastThrownObject)
CDAC_TYPE_FIELD(Thread, pointer, LinkNext, cdac_offsets<Thread>::Link)
CDAC_TYPE_END(Thread)

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -4044,7 +4044,10 @@ class Thread
template<>
struct cdac_offsets<Thread>
{
static constexpr size_t Id = offsetof(Thread, m_ThreadId);
static constexpr size_t OSId = offsetof(Thread, m_OSThreadId);
static constexpr size_t ExposedObject = offsetof(Thread, m_ExposedObject);
static constexpr size_t LastThrownObject = offsetof(Thread, m_LastThrownObjectHandle);
static constexpr size_t Link = offsetof(Thread, m_Link);
};

Expand Down
36 changes: 34 additions & 2 deletions src/native/managed/cdacreader/src/Contracts/Thread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ internal record struct ThreadStoreCounts(
int PendingThreadCount,
int DeadThreadCount);

internal record struct ThreadData(
uint Id,
TargetPointer NextThread);

internal interface IThread : IContract
{
static string IContract.Name { get; } = nameof(Thread);
Expand All @@ -33,6 +37,7 @@ static IContract IContract.Create(Target target, int version)

public virtual ThreadStoreData GetThreadStoreData() => throw new NotImplementedException();
public virtual ThreadStoreCounts GetThreadCounts() => throw new NotImplementedException();
public virtual ThreadData GetThreadData(TargetPointer thread) => throw new NotImplementedException();
}

internal readonly struct Thread : IThread
Expand All @@ -51,8 +56,10 @@ internal Thread_1(Target target, TargetPointer threadStore)
_target = target;
_threadStoreAddr = threadStore;

// Get the offset into Thread of the SLink. We use this to find the actual
// first thread from the linked list node contained by the first thread.
Target.TypeInfo type = _target.GetTypeInfo(DataType.Thread);
_threadLinkOffset = (ulong)type.Fields["LinkNext"].Offset;
_threadLinkOffset = (ulong)type.Fields[nameof(Data.Thread.LinkNext)].Offset;
}

ThreadStoreData IThread.GetThreadStoreData()
Expand All @@ -68,7 +75,7 @@ ThreadStoreData IThread.GetThreadStoreData()

return new ThreadStoreData(
threadStore.ThreadCount,
new TargetPointer(threadStore.FirstThreadLink - _threadLinkOffset),
GetThreadFromLink(threadStore.FirstThreadLink),
_target.ReadGlobalPointer(Constants.Globals.FinalizerThread),
_target.ReadGlobalPointer(Constants.Globals.GCThread));
}
Expand All @@ -90,4 +97,29 @@ ThreadStoreCounts IThread.GetThreadCounts()
threadStore.PendingCount,
threadStore.DeadCount);
}

ThreadData IThread.GetThreadData(TargetPointer threadPointer)
{
Data.Thread? thread;
if (!_target.ProcessedData.TryGet(threadPointer, out thread))
{
thread = new Data.Thread(_target, threadPointer);

// Still okay if processed data is already registered by someone else.
_ = _target.ProcessedData.TryRegister(threadPointer, thread);
}

return new ThreadData(
thread.Id,
GetThreadFromLink(thread.LinkNext));
}

private TargetPointer GetThreadFromLink(TargetPointer threadLink)
{
if (threadLink == TargetPointer.Null)
return TargetPointer.Null;

// Get the address of the thread containing the link
return new TargetPointer(threadLink - _threadLinkOffset);
}
}
18 changes: 18 additions & 0 deletions src/native/managed/cdacreader/src/Data/Thread.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Diagnostics.DataContractReader.Data;

internal sealed class Thread
{
public Thread(Target target, TargetPointer address)
{
Target.TypeInfo type = target.GetTypeInfo(DataType.Thread);

Id = target.Read<uint>(address + (ulong)type.Fields[nameof(Id)].Offset);
LinkNext = target.ReadPointer(address + (ulong)type.Fields[nameof(LinkNext)].Offset);
}

public uint Id { get; init; }
internal TargetPointer LinkNext { get; init; }
}
19 changes: 18 additions & 1 deletion src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,24 @@ public int GetBreakingChangeVersion()
public unsafe int GetSyncBlockCleanupData(ulong addr, void* data) => HResults.E_NOTIMPL;
public unsafe int GetSyncBlockData(uint number, void* data) => HResults.E_NOTIMPL;
public unsafe int GetThreadAllocData(ulong thread, void* data) => HResults.E_NOTIMPL;
public unsafe int GetThreadData(ulong thread, DacpThreadData* data) => HResults.E_NOTIMPL;

public unsafe int GetThreadData(ulong thread, DacpThreadData* data)
{
try
{
Contracts.IThread contract = _target.Contracts.Thread;
Contracts.ThreadData threadData = contract.GetThreadData(thread);
data->corThreadId = (int)threadData.Id;
data->nextThread = threadData.NextThread;
}
catch (Exception ex)
{
return ex.HResult;
}

// TODO: [cdac] Implement/populate rest of thread data fields
return HResults.E_NOTIMPL;
}
public unsafe int GetThreadFromThinlockID(uint thinLockId, ulong* pThread) => HResults.E_NOTIMPL;
public unsafe int GetThreadLocalModuleData(ulong thread, uint index, void* data) => HResults.E_NOTIMPL;
public unsafe int GetThreadpoolData(void* data) => HResults.E_NOTIMPL;
Expand Down