From 637900c4d1792d41b0c195904c079277cd80caf9 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Thu, 7 Mar 2019 10:35:25 -0800 Subject: [PATCH] Fix control C trap hang in the debugger (#23090) --- src/debug/di/process.cpp | 46 +++++++++++++++++++++---------------------- src/debug/di/rspriv.h | 3 +++ src/debug/di/shimcallback.cpp | 12 ++++++----- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp index 150d0e3..1536f8c 100644 --- a/src/debug/di/process.cpp +++ b/src/debug/di/process.cpp @@ -106,7 +106,7 @@ STDAPI DLLEXPORT OpenVirtualProcessImpl( pDataTarget, // takes a reference hDacModule, NULL, // Cordb - &pd, // 0 for V3 cases (pShim == NULL). + &pd, // 0 for V3 cases (pShim == NULL). NULL, // no Shim in V3 cases &pProcess)); @@ -4921,7 +4921,7 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_DATA_BREAKPOINT: { _ASSERTE(pThread != NULL); - + { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback4->DataBreakpoint(static_cast(this), pThread, reinterpret_cast(&(pEvent->DataBreakpointData.context)), sizeof(CONTEXT)); @@ -5642,24 +5642,6 @@ void CordbProcess::RawDispatchEvent( PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); hr = pCallback1->ControlCTrap((ICorDebugProcess*) this); } - - { - RSLockHolder ch(this->GetStopGoLock()); - - DebuggerIPCEvent eventControlCResult; - - InitIPCEvent(&eventControlCResult, - DB_IPCE_CONTROL_C_EVENT_RESULT, - false, - VMPTR_AppDomain::NullPtr()); - - // Indicate whether the debugger has handled the event. - eventControlCResult.hr = hr; - - // Send the reply to the LS. - SendIPCEvent(&eventControlCResult, sizeof(eventControlCResult)); - } // release SG lock - } break; @@ -6497,7 +6479,7 @@ HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE hr = E_INVALIDARG; } else - { + { DT_CONTEXT* managedContext; hr = thread->GetManagedContext(&managedContext); *pContext = *managedContext; @@ -6576,7 +6558,7 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE { RSLockHolder ch(GetProcess()->GetStopGoLock()); RSLockHolder lockHolder(GetProcessLock()); - + EX_TRY { CordbThread* thread = this->TryLookupThreadByVolatileOSId(threadID); @@ -6595,7 +6577,7 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE } EX_END_CATCH(SwallowAllExceptions) - + } return hr; } @@ -15245,3 +15227,21 @@ bool CordbProcess::IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThrea CordbThread * pCordbThread = static_cast (pICorDebugThread); return GetDAC()->IsThreadSuspendedOrHijacked(pCordbThread->m_vmThreadToken); } + +void CordbProcess::HandleControlCTrapResult(HRESULT result) +{ + RSLockHolder ch(GetStopGoLock()); + + DebuggerIPCEvent eventControlCResult; + + InitIPCEvent(&eventControlCResult, + DB_IPCE_CONTROL_C_EVENT_RESULT, + false, + VMPTR_AppDomain::NullPtr()); + + // Indicate whether the debugger has handled the event. + eventControlCResult.hr = result; + + // Send the reply to the LS. + SendIPCEvent(&eventControlCResult, sizeof(eventControlCResult)); +} diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h index fef79d8..64d1fae 100644 --- a/src/debug/di/rspriv.h +++ b/src/debug/di/rspriv.h @@ -3273,6 +3273,9 @@ public: bool IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread); + // Handle the result of the ctrlC trap. + void HandleControlCTrapResult(HRESULT result); + // Helper to get ProcessDescriptor internally. const ProcessDescriptor* GetProcessDescriptor(); diff --git a/src/debug/di/shimcallback.cpp b/src/debug/di/shimcallback.cpp index e987f9b..fab5fbf 100644 --- a/src/debug/di/shimcallback.cpp +++ b/src/debug/di/shimcallback.cpp @@ -868,7 +868,7 @@ HRESULT ShimProxyCallback::ControlCTrap(ICorDebugProcess * pProcess) class ControlCTrapEvent : public ManagedEvent { // callbacks parameters. These are strong references - RSExtSmartPtr m_pProcess; + RSExtSmartPtr m_pProcess; public: // Ctor @@ -880,7 +880,12 @@ HRESULT ShimProxyCallback::ControlCTrap(ICorDebugProcess * pProcess) HRESULT Dispatch(DispatchArgs args) { - return args.GetCallback1()->ControlCTrap(m_pProcess); + HRESULT hr = args.GetCallback1()->ControlCTrap(m_pProcess); + + // Pass the callback result to the CordbProcess + CordbProcess *proc = static_cast((ICorDebugProcess*) m_pProcess); + proc->HandleControlCTrapResult(hr); + return hr; } }; // end class ControlCTrapEvent @@ -1417,6 +1422,3 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT m_pShim->GetManagedEventQueue()->QueueEvent(new DataBreakpointEvent(pProcess, pThread, pContext, contextSize)); return S_OK; } - - - -- 2.7.4