From a4a4220524eab09288445eabf645944ade04eb80 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 27 Jun 2018 11:15:04 -0700 Subject: [PATCH] Get/Set the ThreadContext natively if the debuggee is block on garbage collection events Commit migrated from https://github.com/dotnet/coreclr/commit/59acd546c2d326e8a4ec11f078a1f0edde4dabaa --- src/coreclr/src/debug/di/process.cpp | 29 ++++++++++++++++++++++++----- src/coreclr/src/debug/di/rspriv.h | 4 +++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/debug/di/process.cpp b/src/coreclr/src/debug/di/process.cpp index 64446cd..718fff2 100644 --- a/src/coreclr/src/debug/di/process.cpp +++ b/src/coreclr/src/debug/di/process.cpp @@ -984,7 +984,8 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_pEventChannel(NULL), m_fAssertOnTargetInconsistency(false), m_runtimeOffsetsInitialized(false), - m_writableMetadataUpdateMode(LegacyCompatPolicy) + m_writableMetadataUpdateMode(LegacyCompatPolicy), + m_isBlockedOnGarbageCollectionEvent(false) { _ASSERTE((m_id == 0) == (pShim == NULL)); @@ -3644,6 +3645,8 @@ HRESULT CordbProcess::Continue(BOOL fIsOutOfBand) { PUBLIC_API_ENTRY(this); + this->m_isBlockedOnGarbageCollectionEvent = false; + if (m_pShim == NULL) // This API is moved off to the shim { // bias towards failing with CORDBG_E_NUETERED. @@ -4911,6 +4914,7 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_BEFORE_GARBAGE_COLLECTION: { { + this->m_isBlockedOnGarbageCollectionEvent = true; PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback4->BeforeGarbageCollection(static_cast(this)); } @@ -4920,6 +4924,7 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_AFTER_GARBAGE_COLLECTION: { { + this->m_isBlockedOnGarbageCollectionEvent = true; PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback4->AfterGarbageCollection(static_cast(this)); } @@ -6501,9 +6506,16 @@ HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE } else { - DT_CONTEXT* managedContext; - hr = thread->GetManagedContext(&managedContext); - *pContext = *managedContext; + if (this->m_isBlockedOnGarbageCollectionEvent) + { + hr = this->GetDataTarget()->GetThreadContext(threadID, CONTEXT_FULL, contextSize, context); + } + else + { + DT_CONTEXT* managedContext; + hr = thread->GetManagedContext(&managedContext); + *pContext = *managedContext; + } } } EX_CATCH @@ -6591,7 +6603,14 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE hr = E_INVALIDARG; } - hr = thread->SetManagedContext(pContext); + if (this->m_isBlockedOnGarbageCollectionEvent) + { + hr = this->m_pMutableDataTarget->SetThreadContext(threadID, contextSize, context); + } + else + { + hr = thread->SetManagedContext(pContext); + } } EX_CATCH { diff --git a/src/coreclr/src/debug/di/rspriv.h b/src/coreclr/src/debug/di/rspriv.h index a9f5893..d3de665 100644 --- a/src/coreclr/src/debug/di/rspriv.h +++ b/src/coreclr/src/debug/di/rspriv.h @@ -3749,7 +3749,6 @@ public: // This is also used in fake-native debugging scenarios. bool m_loaderBPReceived; - private: // MetaData dispenser. @@ -4114,6 +4113,9 @@ private: // controls how metadata updated in the target is handled WriteableMetadataUpdateMode m_writableMetadataUpdateMode; + + // TODO: Comments + bool m_isBlockedOnGarbageCollectionEvent; }; // Some IMDArocess APIs are supported as interop-only. -- 2.7.4