From ce212d5c8c7fc528fe511cc2e1f7cfb7c4862a0d Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 May 2026 11:08:00 -0700 Subject: [PATCH 1/5] making IPC events platform neutral --- src/coreclr/debug/di/breakpoint.cpp | 4 +- src/coreclr/debug/di/divalue.cpp | 2 +- src/coreclr/debug/di/module.cpp | 2 +- src/coreclr/debug/di/process.cpp | 240 +++------- src/coreclr/debug/di/rspriv.h | 18 +- src/coreclr/debug/di/rsthread.cpp | 14 +- src/coreclr/debug/di/shimcallback.cpp | 13 +- src/coreclr/debug/di/valuehome.cpp | 20 +- src/coreclr/debug/ee/debugger.cpp | 306 ++----------- src/coreclr/debug/ee/debugger.h | 31 +- src/coreclr/debug/ee/funceval.cpp | 20 +- src/coreclr/debug/inc/dbgipcevents.h | 421 +++++++----------- src/coreclr/debug/inc/dbgipceventtypes.h | 14 - .../debug/shared/dbgtransportsession.cpp | 48 +- src/coreclr/vm/dbginterface.h | 10 - src/coreclr/vm/eedbginterface.h | 3 - src/coreclr/vm/eedbginterfaceimpl.cpp | 11 - src/coreclr/vm/eedbginterfaceimpl.h | 3 - 18 files changed, 308 insertions(+), 872 deletions(-) diff --git a/src/coreclr/debug/di/breakpoint.cpp b/src/coreclr/debug/di/breakpoint.cpp index 068bd111f9bce4..7ab55940df3c10 100644 --- a/src/coreclr/debug/di/breakpoint.cpp +++ b/src/coreclr/debug/di/breakpoint.cpp @@ -202,12 +202,12 @@ HRESULT CordbFunctionBreakpoint::Activate(BOOL fActivate) pEvent->BreakpointData.funcMetadataToken = m_code->GetMetadataToken(); pEvent->BreakpointData.vmAssembly = m_code->GetModule()->GetRuntimeAssembly(); - pEvent->BreakpointData.encVersion = m_code->GetVersion(); + pEvent->BreakpointData.encVersion = (UINT)(m_code->GetVersion()); BOOL codeIsIL = m_code->IsIL(); pEvent->BreakpointData.isIL = m_offsetIsIl ? true : false; - pEvent->BreakpointData.offset = m_offset; + pEvent->BreakpointData.offset = (UINT)m_offset; if (codeIsIL) { pEvent->BreakpointData.nativeCodeMethodDescToken = pEvent->BreakpointData.nativeCodeMethodDescToken.NullPtr(); diff --git a/src/coreclr/debug/di/divalue.cpp b/src/coreclr/debug/di/divalue.cpp index ab5883fc342fef..709b33281d8736 100644 --- a/src/coreclr/debug/di/divalue.cpp +++ b/src/coreclr/debug/di/divalue.cpp @@ -460,7 +460,7 @@ HRESULT CordbValue::InternalCreateHandle(CorDebugHandleType handleType, m_appdomain->GetADToken()); CORDB_ADDRESS addr = GetValueHome() != NULL ? GetValueHome()->GetAddress() : (CORDB_ADDRESS)NULL; - event.CreateHandle.objectToken = CORDB_ADDRESS_TO_PTR(addr); + event.CreateHandle.objectToken = addr; event.CreateHandle.handleType = handleType; // Note: two-way event here... diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 5249fa264bb343..50b78b0bb1273e 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -424,7 +424,7 @@ class CleanupRemoteBuffer true, pModule->GetAppDomain()->GetADToken()); - event.MetadataUpdateRequest.pMetadataStart = CORDB_ADDRESS_TO_PTR(bufferMetaData.pAddress); + event.MetadataUpdateRequest.pMetadataStart = bufferMetaData.pAddress; // Note: two-way event here... IfFailThrow(pProcess->SendIPCEvent(&event, sizeof(DebuggerIPCEvent))); diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index b47cc24cf3b563..f1ea0be2af89a0 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -4862,7 +4862,7 @@ void CordbProcess::RawDispatchEvent( { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback4->DataBreakpoint(static_cast(this), pThread, reinterpret_cast(&(pEvent->DataBreakpointData.context)), sizeof(CONTEXT)); + pCallback4->DataBreakpoint(static_cast(this), pThread, reinterpret_cast(&(pEvent->DataBreakpointData.context)), pEvent->DataBreakpointData.contextSize); } break; } @@ -5039,42 +5039,6 @@ void CordbProcess::RawDispatchEvent( } break; - case DB_IPCE_CREATE_CONNECTION: - { - STRESS_LOG1(LF_CORDB, LL_INFO100, - "RCET::HRCE: Connection change %d \n", - pEvent->CreateConnection.connectionId); - - // pass back the connection id and the connection name. - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback2->CreateConnection( - this, - pEvent->CreateConnection.connectionId, - const_cast (pEvent->CreateConnection.wzConnectionName.GetString())); - } - break; - - case DB_IPCE_DESTROY_CONNECTION: - { - STRESS_LOG1(LF_CORDB, LL_INFO100, - "RCET::HRCE: Connection destroyed %d \n", - pEvent->ConnectionChange.connectionId); - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback2->DestroyConnection(this, pEvent->ConnectionChange.connectionId); - } - break; - - case DB_IPCE_CHANGE_CONNECTION: - { - STRESS_LOG1(LF_CORDB, LL_INFO100, - "RCET::HRCE: Connection changed %d \n", - pEvent->ConnectionChange.connectionId); - - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback2->ChangeConnection(this, pEvent->ConnectionChange.connectionId); - } - break; - case DB_IPCE_UNLOAD_MODULE: { STRESS_LOG3(LF_CORDB, LL_INFO100, "RCET::HRCE: unload module on thread %#x Mod:0x%x AD:0x%08x\n", @@ -5206,49 +5170,26 @@ void CordbProcess::RawDispatchEvent( _ASSERTE(pThread != NULL); _ASSERTE(pAppDomain != NULL); - const WCHAR * pszContent = pEvent->FirstLogMessage.szContent.GetString(); + // szCategory and szContent are CORDB_ADDRESS pointers into the target. + // Read the null-terminated strings via ReadVirtual. The NewArrayHolders + // ensure cleanup when this block exits. + NewArrayHolder wszCategory( + ReadTargetNullTerminatedString(pEvent->FirstLogMessage.szCategory)); + NewArrayHolder wszContent( + ReadTargetNullTerminatedString(pEvent->FirstLogMessage.szContent)); + { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); pCallback1->LogMessage( pAppDomain, pThread, pEvent->FirstLogMessage.iLevel, - const_cast (pEvent->FirstLogMessage.szCategory.GetString()), - const_cast (pszContent)); + wszCategory, + wszContent); } } break; - case DB_IPCE_LOGSWITCH_SET_MESSAGE: - { - - LOG((LF_CORDB, LL_INFO10000, - "[%x] RCET::DRCE: Log Switch Setting Message.\n", - GetCurrentThreadId())); - - _ASSERTE(pThread != NULL); - - const WCHAR *pstrLogSwitchName = pEvent->LogSwitchSettingMessage.szSwitchName.GetString(); - const WCHAR *pstrParentName = pEvent->LogSwitchSettingMessage.szParentSwitchName.GetString(); - - // from the thread object get the appdomain object - _ASSERTE(pAppDomain == pThread->m_pAppDomain); - _ASSERTE (pAppDomain != NULL); - - { - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - pCallback1->LogSwitch( - pAppDomain, - pThread, - pEvent->LogSwitchSettingMessage.iLevel, - pEvent->LogSwitchSettingMessage.iReason, - const_cast (pstrLogSwitchName), - const_cast (pstrParentName)); - - } - } - - break; case DB_IPCE_CUSTOM_NOTIFICATION: { _ASSERTE(pThread != NULL); @@ -6027,7 +5968,7 @@ HRESULT CordbProcess::IsTransitionStub(CORDB_ADDRESS address, BOOL *pfTransition InitIPCEvent(&eventData, DB_IPCE_IS_TRANSITION_STUB, true, VMPTR_AppDomain::NullPtr()); - eventData.IsTransitionStub.address = CORDB_ADDRESS_TO_PTR(address); + eventData.IsTransitionStub.address = address; hr = SendIPCEvent(&eventData, sizeof(eventData)); hr = WORST_HR(hr, eventData.hr); @@ -8377,20 +8318,6 @@ COM_METHOD CordbProcess::ModifyLogSwitch(_In_z_ WCHAR *pLogSwitchName, LONG lLev ATT_REQUIRE_STOPPED_MAY_FAIL(this); HRESULT hr = S_OK; - - _ASSERTE (pLogSwitchName != NULL); - - DebuggerIPCEvent *event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE); - InitIPCEvent(event, DB_IPCE_MODIFY_LOGSWITCH, false, VMPTR_AppDomain::NullPtr()); - event->LogSwitchSettingMessage.iLevel = lLevel; - event->LogSwitchSettingMessage.szSwitchName.SetStringTruncate(pLogSwitchName); - - hr = m_cordb->SendIPCEvent(this, event, CorDBIPC_BUFFER_SIZE); - hr = WORST_HR(hr, event->hr); - - LOG((LF_CORDB, LL_INFO10000, "[%x] CP::ModifyLogSwitch: ModifyLogSwitch sent.\n", - GetCurrentThreadId())); - return hr; } @@ -9262,63 +9189,71 @@ void Ls_Rs_StringBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget) } //--------------------------------------------------------------------------------------- -// Marshals the arguments in a managed-debug event. +// Read a null-terminated WCHAR string from the target process. +// The caller owns the returned buffer and should free it with delete[] (or wrap +// it in a NewArrayHolder for automatic cleanup). // // Arguments: -// pManagedEvent - (IN/OUT) debug event to marshal. Events are not usable in the host process -// until they are marshalled. This will marshal the event in-place, and may convert -// some target addresses to host addresses. +// targetAddr - CORDB_ADDRESS of the null-terminated WCHAR string in the target. // -// Return Value: -// S_OK on success. Else Error. -// -// Assumptions: -// Target is currently stopped and inspectable. -// After the event is marshalled, it has resources that must be cleaned up -// by calling code:DeleteIPCEventHelper. -// -// Notes: -// Call a Copy function (CopyManagedEventFromTarget, CopyRCEventFromIPCBlock)to -// get the event to marshal. -// This will marshal args from the target into the host. -// The debug event is fixed size. But since the debuggee is stopped, this can copy -// arbitrary-length buffers out of of the debuggee. +// Returns: +// A heap-allocated WCHAR* copy of the string, or NULL if targetAddr is 0. // -// This could be rolled into code:CordbProcess::RawDispatchEvent +// Throws on ReadVirtual failure. //--------------------------------------------------------------------------------------- -void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) +WCHAR * CordbProcess::ReadTargetNullTerminatedString(CORDB_ADDRESS targetAddr) { - CONTRACTL + if (targetAddr == 0) { - THROWS; - - // Event has already been copied, now we do some quick Marshalling. - // Thsi should be a private local copy, and not the one in the IPC block or Target. - PRECONDITION(CheckPointer(pManagedEvent)); + return NULL; } - CONTRACTL_END; - IfFailThrow(pManagedEvent->hr); + // Read the string in chunks to find the null terminator, similar to DacInstantiateStringW. + const ULONG32 chunkSize = 256; + const ULONG32 maxChars = 512 * 1024; // 1 MB cap to prevent unbounded allocation from corrupt targets + NewArrayHolder buffer(NULL); + ULONG32 totalChars = 0; - // This may throw part way through marshalling. But that's ok because - // code:DeleteIPCEventHelper can cleanup a partially-marshalled event. - - // Do a pre-processing on the event - switch (pManagedEvent->type & DB_IPCE_TYPE_MASK) + for (;;) { - case DB_IPCE_FIRST_LOG_MESSAGE: + if (totalChars >= maxChars) { - pManagedEvent->FirstLogMessage.szContent.CopyLSDataToRS(this->m_pDACDataTarget); - break; + ThrowHR(CORDBG_E_TARGET_INCONSISTENT); } - default: - break; - } + ULONG32 newSize = totalChars + chunkSize; + WCHAR * newBuffer = new WCHAR[newSize]; + if (buffer != NULL) + { + memcpy(newBuffer, (WCHAR *)buffer, totalChars * sizeof(WCHAR)); + } + buffer = newBuffer; + ULONG32 cbRead; + HRESULT hr = m_pDACDataTarget->ReadVirtual( + targetAddr + totalChars * sizeof(WCHAR), + reinterpret_cast(buffer.GetValue() + totalChars), + chunkSize * sizeof(WCHAR), + &cbRead); + IfFailThrow(hr); -} + ULONG32 charsRead = cbRead / sizeof(WCHAR); + for (ULONG32 i = 0; i < charsRead; i++) + { + if (buffer[totalChars + i] == W('\0')) + { + buffer.SuppressRelease(); + return (WCHAR *)buffer; + } + } + totalChars += charsRead; + if (charsRead < chunkSize) + { + ThrowHR(CORDBG_E_TARGET_INCONSISTENT); + } + } +} //--------------------------------------------------------------------------------------- // Copy a managed debug event from the target process into this local process @@ -9333,7 +9268,6 @@ void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) // * False if this does not belong to this instance of ICorDebug. (perhaps it's an event // intended for another instance of the CLR in the target, or some rogue user code happening // to use our exception code). -// In either case, the event can still be cleaned up via code:DeleteIPCEventHelper. // // Throws on error. In the error case, the contents of pLocalManagedEvent are undefined. // They may have been partially copied from the target. The local managed event does not own @@ -9347,7 +9281,6 @@ void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent) // This should always succeed in the well-behaved case. However, A bad debuggee can // always send a poor-formed debug event. // We don't distinguish between a badly formed event and an event that's not ours. -// The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent) // //--------------------------------------------------------------------------------------- bool CordbProcess::CopyManagedEventFromTarget( @@ -9357,7 +9290,6 @@ bool CordbProcess::CopyManagedEventFromTarget( _ASSERTE(pRecord != NULL); _ASSERTE(pLocalManagedEvent != NULL); - // Initialize the event enough such backout code can call code:DeleteIPCEventHelper. pLocalManagedEvent->type = DB_IPCE_DEBUGGER_INVALID; // Ensure we have a CLR instance ID by now. Either we had one already, or we're in @@ -9460,7 +9392,6 @@ HRESULT CordbProcess::EnsureClrInstanceIdSet() // This is copying from a shared-memory block, which is treated as local memory. // This just does a raw Byte copy, but does not do any Marshalling. // This does no validation on the event. -// The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent) // //--------------------------------------------------------------------------------------- void inline CordbProcess::CopyRCEventFromIPCBlock(DebuggerIPCEvent * pLocalManagedEvent) @@ -9972,8 +9903,7 @@ void CordbProcess::HandleRCEvent( return; } - // Marshals over some standard data from event. - MarshalManagedEvent(pManagedEvent); + IfFailThrow(pManagedEvent->hr); STRESS_LOG4(LF_CORDB, LL_INFO1000, "RCET::TP: Got %s for AD 0x%x, proc 0x%x(%d)\n", IPCENames::GetName(pManagedEvent->type), VmPtrToCookie(pManagedEvent->vmAppDomain), this->m_id, this->m_id); @@ -10385,7 +10315,7 @@ HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess, EX_TRY { - pProcess->MarshalManagedEvent(pEvent); + IfFailThrow(pEvent->hr); STRESS_LOG4(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: Got %s for AD 0x%x, proc 0x%x(%d)\n", IPCENames::GetName(pEvent->type), @@ -10611,44 +10541,6 @@ void CordbWin32EventThread::ThreadProc() #endif } -// Define a holder that calls code:DeleteIPCEventHelper -using DeleteIPCEventHolder = SpecializedWrapper; - -//--------------------------------------------------------------------------------------- -// -// Helper to clean up IPCEvent before deleting it. -// This must be called after an event is marshalled via code:CordbProcess::MarshalManagedEvent -// -// Arguments: -// pManagedEvent - managed event to delete. -// -// Notes: -// This can delete a partially marshalled event. -// -void DeleteIPCEventHelper(DebuggerIPCEvent *pManagedEvent) -{ - CONTRACTL - { - // This is backout code that shouldn't need to throw. - NOTHROW; - } - CONTRACTL_END; - if (pManagedEvent == NULL) - { - return; - } - switch (pManagedEvent->type & DB_IPCE_TYPE_MASK) - { - case DB_IPCE_FIRST_LOG_MESSAGE: - pManagedEvent->FirstLogMessage.szContent.CleanUp(); - break; - - default: - break; - } - delete [] (BYTE *)pManagedEvent; -} - //--------------------------------------------------------------------------------------- // Handle a CLR specific notification event. // @@ -11406,8 +11298,8 @@ HRESULT CordbProcess::Filter( // 2. Notifications may come on unmanaged threads if they're coming from MDAs or CLR internal events // fired before the thread is created. // - BYTE * pManagedEventBuffer = new BYTE[CorDBIPC_BUFFER_SIZE]; - DeleteIPCEventHolder pManagedEvent(reinterpret_cast(pManagedEventBuffer)); + NewArrayHolder pManagedEventBuffer(new BYTE[CorDBIPC_BUFFER_SIZE]); + DebuggerIPCEvent * pManagedEvent = reinterpret_cast(pManagedEventBuffer.GetValue()); bool fOwner = CopyManagedEventFromTarget(pRecord, pManagedEvent); if (fOwner) @@ -11421,8 +11313,6 @@ HRESULT CordbProcess::Filter( // up exceptions for the CLR. *pContinueStatus = DBG_CONTINUE; } - - // holder will invoke DeleteIPCEventHelper(pManagedEvent). } #ifdef OUT_OF_PROCESS_SETTHREADCONTEXT else if (dwFirstChance && pRecord->ExceptionCode == STATUS_BREAKPOINT) @@ -14724,7 +14614,7 @@ HRESULT CordbProcess::ReleaseRemoteBuffer(void **ppBuffer) VMPTR_AppDomain::NullPtr()); // Indicate the buffer to release - event.ReleaseBuffer.pBuffer = (*ppBuffer); + event.ReleaseBuffer.pBuffer = (CORDB_ADDRESS)(*ppBuffer); // Make the request, which is synchronous HRESULT hr = SendIPCEvent(&event, sizeof(event)); diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 69f2876a8c1650..316e237f52adef 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -2743,9 +2743,6 @@ const int DEBUG_EVENTQUEUE_SIZE = 30; const int DEBUG_EVENTQUEUE_SIZE = 10; #endif -void DeleteIPCEventHelper(DebuggerIPCEvent *pDel); - - // Private interface on CordbProcess that ShimProcess needs to emulate V2 functionality. // The fact that we need private hooks means that V3 is not sufficiently finished to allow building // a V2 debugger. This interface should shrink over time (and eventually go away) as the functionality gets exposed @@ -3225,8 +3222,9 @@ class CordbProcess : // Queue the RC event. void QueueRCEvent(DebuggerIPCEvent * pManagedEvent); - // This marshals a managed debug event from the - void MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent); + // Read a null-terminated WCHAR string from the target process. + // Caller owns the returned buffer (use NewArrayHolder for RAII cleanup). + _Ret_maybenull_ WCHAR * ReadTargetNullTerminatedString(CORDB_ADDRESS targetAddr); // This copies a managed debug event from the IPC block and to pManagedEvent. // The event still needs to be marshalled. @@ -3423,9 +3421,7 @@ class CordbProcess : memset( ipce, 0, sizeof(DebuggerIPCEvent) ); _ASSERTE((!vmAppDomain.IsNull()) || - type == DB_IPCE_GET_GCHANDLE_INFO || type == DB_IPCE_ENABLE_LOG_MESSAGES || - type == DB_IPCE_MODIFY_LOGSWITCH || type == DB_IPCE_ASYNC_BREAK || type == DB_IPCE_CONTINUE || type == DB_IPCE_GET_BUFFER || @@ -3436,11 +3432,8 @@ class CordbProcess : type == DB_IPCE_CONTROL_C_EVENT_RESULT || type == DB_IPCE_SET_REFERENCE || type == DB_IPCE_SET_ALL_DEBUG_STATE || - type == DB_IPCE_GET_THREAD_FOR_TASKID || type == DB_IPCE_DETACH_FROM_PROCESS || type == DB_IPCE_INTERCEPT_EXCEPTION || - type == DB_IPCE_GET_NGEN_COMPILER_FLAGS || - type == DB_IPCE_SET_NGEN_COMPILER_FLAGS || type == DB_IPCE_SET_VALUE_CLASS); ipce->type = type; @@ -3450,7 +3443,6 @@ class CordbProcess : ipce->vmThread = VMPTR_Thread::NullPtr(); ipce->replyRequired = twoWay; ipce->asyncSend = false; - ipce->next = NULL; } // Looks up a previously constructed CordbClass instance without creating. May return NULL if the @@ -6255,7 +6247,7 @@ class CordbThread : public CordbBase, public ICorDebugThread, // we need to communicate the IP back to LS. So we stash the address of where // to store the IP here and stuff it in on RemapFunction. // If we're not at an outstanding RemapOpportunity, this will be NULL - REMOTE_PTR m_EnCRemapFunctionIP; + CORDB_ADDRESS m_EnCRemapFunctionIP; private: void ClearStackFrameCache(); @@ -9926,7 +9918,7 @@ class CordbEval : public CordbBase, public ICorDebugEval, public ICorDebugEval2 bool m_complete; bool m_successful; bool m_aborted; - void *m_resultAddr; + CORDB_ADDRESS m_resultAddr; // This is an OBJECTHANDLE on the LS if func-eval creates a strong handle. // This is a resource in the left-side and must be cleaned up in the left-side. diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 5636d7bf48da3d..9e9eef25c2f2b0 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -2509,7 +2509,7 @@ HRESULT CordbThread::SetRemapIP(SIZE_T offset) } // Write the value of the remap offset into the left side - HRESULT hr = GetProcess()->SafeWriteStruct(PTR_TO_CORDB_ADDRESS(m_EnCRemapFunctionIP), &offset); + HRESULT hr = GetProcess()->SafeWriteStruct(m_EnCRemapFunctionIP, &offset); // Prevent SetRemapIP from being called twice for the same RemapOpportunity // If we don't get any calls to RemapFunction, this member will be cleared in @@ -9096,7 +9096,7 @@ CordbEval::CordbEval(CordbThread *pThread) m_complete(false), m_successful(false), m_aborted(false), - m_resultAddr(NULL), + m_resultAddr((CORDB_ADDRESS)0), m_evalDuringException(false) { m_vmObjectHandle = VMPTR_OBJECTHANDLE::NullPtr(); @@ -9274,7 +9274,7 @@ HRESULT CordbEval::GatherArgInfo(ICorDebugValue *pValue, pValue->GetAddress(&addr); - argData->argAddr = CORDB_ADDRESS_TO_PTR(addr); + argData->argAddr = addr; argData->argElementType = ty; argData->argIsHandleValue = false; @@ -9308,7 +9308,7 @@ HRESULT CordbEval::GatherArgInfo(ICorDebugValue *pValue, // buffer area so the left side can get it. CordbReferenceValue *rv; rv = static_cast(pValue); - argData->argIsLiteral = rv->CopyLiteralData(argData->argLiteralData); + argData->argIsLiteral = rv->CopyLiteralData(reinterpret_cast(argData->argLiteralData)); if (rv->GetValueHome()) { rv->GetValueHome()->CopyToIPCEType(&(argData->argHome)); @@ -9352,7 +9352,7 @@ HRESULT CordbEval::GatherArgInfo(ICorDebugValue *pValue, void *buffer = NULL; IfFailRet(m_thread->GetProcess()->GetAndWriteRemoteBuffer(m_thread->GetAppDomain(), bufferSize, bufferFrom, &buffer)); - argData->fullArgType = buffer; + argData->fullArgType = (CORDB_ADDRESS)buffer; argData->fullArgTypeNodeCount = fullArgTypeNodeCount; // Is it enregistered? if ((addr == (CORDB_ADDRESS)NULL) && (pVCObjVal->GetValueHome() != NULL)) @@ -9371,7 +9371,7 @@ HRESULT CordbEval::GatherArgInfo(ICorDebugValue *pValue, // Is this a literal value? If, we'll copy the data to the // buffer area so the left side can get it. CordbGenericValue *gv = (CordbGenericValue*)pValue; - argData->argIsLiteral = gv->CopyLiteralData(argData->argLiteralData); + argData->argIsLiteral = gv->CopyLiteralData(reinterpret_cast(argData->argLiteralData)); // Is it enregistered? if ((addr == (CORDB_ADDRESS)NULL) && (gv->GetValueHome() != NULL)) { @@ -10160,7 +10160,7 @@ HRESULT CordbEval::NewStringWithLength(LPCWSTR wszString, UINT iLength) // Length of the string? Don't account for null as COMString::NewString is length-based - SIZE_T cbString = iLength * sizeof(WCHAR); + UINT cbString = (UINT)(iLength * sizeof(WCHAR)); // Remember that we're doing a func eval for a new string. m_function = NULL; diff --git a/src/coreclr/debug/di/shimcallback.cpp b/src/coreclr/debug/di/shimcallback.cpp index 98fe5d8f56ea12..f557686c015910 100644 --- a/src/coreclr/debug/di/shimcallback.cpp +++ b/src/coreclr/debug/di/shimcallback.cpp @@ -1372,7 +1372,7 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT // callbacks parameters. These are strong references RSExtSmartPtr m_pProcess; RSExtSmartPtr m_pThread; - CONTEXT m_context; + NewArrayHolder m_context; ULONG32 m_contextSize; public: @@ -1383,14 +1383,17 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT this->m_pProcess.Assign(pProcess); this->m_pThread.Assign(pThread); - _ASSERTE(contextSize == sizeof(CONTEXT)); - this->m_contextSize = min(contextSize, (ULONG32)sizeof(CONTEXT)); - memcpy(&(this->m_context), pContext, this->m_contextSize); + this->m_contextSize = contextSize; + m_context = new (nothrow) BYTE[this->m_contextSize]; + if (m_context != NULL) + memcpy(m_context, pContext, this->m_contextSize); } HRESULT Dispatch(DispatchArgs args) { - return args.GetCallback4()->DataBreakpoint(m_pProcess, m_pThread, reinterpret_cast(&m_context), m_contextSize); + if (m_context == NULL) + return E_OUTOFMEMORY; + return args.GetCallback4()->DataBreakpoint(m_pProcess, m_pThread, m_context, m_contextSize); } }; // end class AfterGarbageCollectionEvent diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index 5a12b504b6241c..ff110cf88875bf 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -30,7 +30,7 @@ void RegValueHome::CopyToIPCEType(RemoteAddress * pRegAddr) { pRegAddr->kind = RAK_REG; pRegAddr->reg1 = m_reg1Info.m_kRegNumber; - pRegAddr->reg1Addr = CORDB_ADDRESS_TO_PTR(m_reg1Info.m_regAddr); + pRegAddr->reg1Addr = m_reg1Info.m_regAddr; pRegAddr->reg1Value = m_reg1Info.m_regValue; } // RegValueHome::CopyToIPCEType @@ -256,10 +256,10 @@ void RegRegValueHome::CopyToIPCEType(RemoteAddress * pRegAddr) { pRegAddr->kind = RAK_REGREG; pRegAddr->reg1 = m_reg1Info.m_kRegNumber; - pRegAddr->reg1Addr = CORDB_ADDRESS_TO_PTR(m_reg1Info.m_regAddr); + pRegAddr->reg1Addr = m_reg1Info.m_regAddr; pRegAddr->reg1Value = m_reg1Info.m_regValue; pRegAddr->u.reg2 = m_reg2Info.m_kRegNumber; - pRegAddr->u.reg2Addr = CORDB_ADDRESS_TO_PTR(m_reg2Info.m_regAddr); + pRegAddr->u.reg2Addr = m_reg2Info.m_regAddr; pRegAddr->u.reg2Value = m_reg2Info.m_regValue; } // RegRegValueHome::CopyToIPCEType @@ -317,7 +317,7 @@ void RegMemValueHome::CopyToIPCEType(RemoteAddress * pRegAddr) { pRegAddr->kind = RAK_REGMEM; pRegAddr->reg1 = m_reg1Info.m_kRegNumber; - pRegAddr->reg1Addr = CORDB_ADDRESS_TO_PTR(m_reg1Info.m_regAddr); + pRegAddr->reg1Addr = m_reg1Info.m_regAddr; pRegAddr->reg1Value = m_reg1Info.m_regValue; pRegAddr->addr = m_memAddr; } // RegMemValueHome::CopyToIPCEType @@ -379,7 +379,7 @@ void MemRegValueHome::CopyToIPCEType(RemoteAddress * pRegAddr) { pRegAddr->kind = RAK_MEMREG; pRegAddr->reg1 = m_reg1Info.m_kRegNumber; - pRegAddr->reg1Addr = CORDB_ADDRESS_TO_PTR(m_reg1Info.m_regAddr); + pRegAddr->reg1Addr = m_reg1Info.m_regAddr; pRegAddr->reg1Value = m_reg1Info.m_regValue; pRegAddr->addr = m_memAddr; } // MemRegValueHome::CopyToIPCEType @@ -917,7 +917,7 @@ void HandleValueHome::SetValue(MemoryRange src, CordbType * pType) event.SetReference.objectRefAddress = NULL; event.SetReference.vmObjectHandle = m_vmObjectHandle; - event.SetReference.newReference = *((void **)src.StartAddress()); + event.SetReference.newReference = PTR_TO_CORDB_ADDRESS(*((void **)src.StartAddress())); // Note: two-way event here... IfFailThrow(m_pProcess->SendIPCEvent(&event, sizeof(DebuggerIPCEvent))); @@ -985,8 +985,8 @@ void VCRemoteValueHome::SetValue(MemoryRange src, CordbType * pType) // Finally, send over the Set Value Class message. m_pProcess->InitIPCEvent(&event, DB_IPCE_SET_VALUE_CLASS, true, VMPTR_AppDomain::NullPtr()); - event.SetValueClass.oldData = CORDB_ADDRESS_TO_PTR(m_remoteValue.pAddress); - event.SetValueClass.newData = buffer; + event.SetValueClass.oldData = m_remoteValue.pAddress; + event.SetValueClass.newData = PTR_TO_CORDB_ADDRESS(buffer); IfFailThrow(pType->TypeToBasicTypeData(&event.SetValueClass.type)); // Note: two-way event here... @@ -1044,9 +1044,9 @@ void RefRemoteValueHome::SetValue(MemoryRange src, CordbType * pType) m_pProcess->InitIPCEvent(&event, DB_IPCE_SET_REFERENCE, true, VMPTR_AppDomain::NullPtr()); - event.SetReference.objectRefAddress = CORDB_ADDRESS_TO_PTR(m_remoteValue.pAddress); + event.SetReference.objectRefAddress = m_remoteValue.pAddress; event.SetReference.vmObjectHandle = VMPTR_OBJECTHANDLE::NullPtr(); - event.SetReference.newReference = *((void **)src.StartAddress()); + event.SetReference.newReference = PTR_TO_CORDB_ADDRESS(*((void **)src.StartAddress())); // Note: two-way event here... IfFailThrow(m_pProcess->SendIPCEvent(&event, sizeof(DebuggerIPCEvent))); diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 1e853b149fbc7c..8f66e4290530fa 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -5769,6 +5769,7 @@ void Debugger::SendDataBreakpoint(Thread *thread, CONTEXT *context, // Send a breakpoint event to the Right Side DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); memcpy(&(ipce->DataBreakpointData.context), context, sizeof(CONTEXT)); + ipce->DataBreakpointData.contextSize = sizeof(CONTEXT); InitIPCEvent(ipce, DB_IPCE_DATA_BREAKPOINT, thread); @@ -6000,7 +6001,7 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP, ipce->EnCRemap.currentVersionNumber = dji->m_encVersion; ipce->EnCRemap.resumeVersionNumber = dji->m_methodInfo->GetCurrentEnCVersion();; ipce->EnCRemap.currentILOffset = currentIP; - ipce->EnCRemap.resumeILOffset = resumeIP; + ipce->EnCRemap.resumeILOffset = PTR_TO_CORDB_ADDRESS(resumeIP); ipce->EnCRemap.funcMetadataToken = pMD->GetMemberDef(); LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: methodDef 0x%x, from version %zx to %zx\n", @@ -7154,7 +7155,7 @@ HRESULT Debugger::SendExceptionHelperAndBlock( ipce->ExceptionCallback2.framePointer = framePointer; ipce->ExceptionCallback2.eventType = eventType; - ipce->ExceptionCallback2.nOffset = nOffset; + ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = dwFlags; ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(exceptionHandle); @@ -7307,7 +7308,7 @@ void Debugger::SendExceptionEventsWorker( ipce->ExceptionCallback2.framePointer = framePointer; ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_USER_FIRST_CHANCE; - ipce->ExceptionCallback2.nOffset = nOffset; + ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0; ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(g_pEEInterface->GetThreadException(pThread)); @@ -7966,7 +7967,7 @@ void Debugger::SendCatchHandlerFound( ipce->ExceptionCallback2.framePointer = fp; ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_CATCH_HANDLER_FOUND; - ipce->ExceptionCallback2.nOffset = nOffset; + ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = dwFlags; ipce->ExceptionCallback2.vmExceptionHandle.SetRawPtr(g_pEEInterface->GetThreadException(pThread)); @@ -9749,7 +9750,7 @@ void Debugger::FuncEvalComplete(Thread* pThread, DebuggerEval *pDE) ipce->FuncEvalComplete.funcEvalKey = pDE->m_funcEvalKey; ipce->FuncEvalComplete.successful = pDE->m_successful; ipce->FuncEvalComplete.aborted = pDE->m_aborted; - ipce->FuncEvalComplete.resultAddr = pDE->m_result; + ipce->FuncEvalComplete.resultAddr = (CORDB_ADDRESS)(pDE->m_result); ipce->FuncEvalComplete.vmAppDomain.SetRawPtr(pDomain); ipce->FuncEvalComplete.vmObjectHandle = pDE->m_vmObjectHandle; @@ -9763,11 +9764,11 @@ void Debugger::FuncEvalComplete(Thread* pThread, DebuggerEval *pDE) _ASSERTE(ipce->FuncEvalComplete.resultType.elementType != ELEMENT_TYPE_VALUETYPE); // We must adjust the result address to point to the right place - ipce->FuncEvalComplete.resultAddr = ArgSlotEndiannessFixup((ARG_SLOT*)ipce->FuncEvalComplete.resultAddr, - GetSizeForCorElementType(ipce->FuncEvalComplete.resultType.elementType)); + ipce->FuncEvalComplete.resultAddr = (CORDB_ADDRESS)(ArgSlotEndiannessFixup((ARG_SLOT*)(CORDB_ADDRESS_TO_PTR(ipce->FuncEvalComplete.resultAddr)), + GetSizeForCorElementType(ipce->FuncEvalComplete.resultType.elementType))); LOG((LF_CORDB, LL_INFO1000, "D::FEC: returned el %04x resultAddr %p\n", - ipce->FuncEvalComplete.resultType.elementType, ipce->FuncEvalComplete.resultAddr)); + ipce->FuncEvalComplete.resultType.elementType, (CORDB_ADDRESS_TO_PTR(ipce->FuncEvalComplete.resultAddr)))); m_pRCThread->SendIPCEvent(); @@ -10477,39 +10478,6 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) } break; - case DB_IPCE_GET_GCHANDLE_INFO: - // Given an unvalidated GC-handle, find out all the info about it to view the object - // at the other end - { - OBJECTHANDLE objectHandle = pEvent->GetGCHandleInfo.GCHandle.GetRawPtr(); - - DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer(); - - _ASSERTE(pIPCResult != NULL); - - InitIPCEvent(pIPCResult, DB_IPCE_GET_GCHANDLE_INFO_RESULT, NULL); - - bool fValid = SUCCEEDED(ValidateGCHandle(objectHandle)); - - AppDomain * pAppDomain = NULL; - - if(fValid) - { - // Get the appdomain - pAppDomain = AppDomain::GetCurrentDomain(); - - _ASSERTE(pAppDomain != NULL); - } - - pIPCResult->hr = S_OK; - pIPCResult->GetGCHandleInfoResult.vmAppDomain.SetRawPtr(pAppDomain); - pIPCResult->GetGCHandleInfoResult.fValid = fValid; - - m_pRCThread->SendIPCReply(); - - } - break; - case DB_IPCE_GET_BUFFER: { GetAndSendBuffer(m_pRCThread, pEvent->GetBuffer.bufSize); @@ -10518,7 +10486,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) case DB_IPCE_RELEASE_BUFFER: { - SendReleaseBuffer(m_pRCThread, pEvent->ReleaseBuffer.pBuffer); + SendReleaseBuffer(m_pRCThread, (CORDB_ADDRESS_TO_PTR(pEvent->ReleaseBuffer.pBuffer))); } break; #ifdef FEATURE_METADATA_UPDATER @@ -10557,13 +10525,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) break; case DB_IPCE_IS_TRANSITION_STUB: - GetAndSendTransitionStubInfo((CORDB_ADDRESS_TYPE*)pEvent->IsTransitionStub.address); - break; - - case DB_IPCE_MODIFY_LOGSWITCH: - g_pEEInterface->DebuggerModifyingLogSwitch (pEvent->LogSwitchSettingMessage.iLevel, - pEvent->LogSwitchSettingMessage.szSwitchName.GetString()); - + GetAndSendTransitionStubInfo((CORDB_ADDRESS_TYPE*)(CORDB_ADDRESS_TO_PTR(pEvent->IsTransitionStub.address))); break; case DB_IPCE_ENABLE_LOG_MESSAGES: @@ -10617,7 +10579,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) pModule, pEvent->SetIP.mdMethod, pDJI, - pEvent->SetIP.offset, + (SIZE_T)pEvent->SetIP.offset, pEvent->SetIP.fIsIL ); } @@ -10746,9 +10708,9 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) InitIPCReply(pEvent, DB_IPCE_SET_REFERENCE_RESULT); - pEvent->hr = SetReference(pEvent->SetReference.objectRefAddress, + pEvent->hr = SetReference(CORDB_ADDRESS_TO_PTR(pEvent->SetReference.objectRefAddress), pEvent->SetReference.vmObjectHandle, - pEvent->SetReference.newReference); + CORDB_ADDRESS_TO_PTR(pEvent->SetReference.newReference)); // Send the result of how the set reference went. m_pRCThread->SendIPCReply(); @@ -10762,8 +10724,8 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) InitIPCReply(pEvent, DB_IPCE_SET_VALUE_CLASS_RESULT); - pEvent->hr = SetValueClass(pEvent->SetValueClass.oldData, - pEvent->SetValueClass.newData, + pEvent->hr = SetValueClass(CORDB_ADDRESS_TO_PTR(pEvent->SetValueClass.oldData), + CORDB_ADDRESS_TO_PTR(pEvent->SetValueClass.newData), &pEvent->SetValueClass.type); // Send the result of how the set reference went. @@ -10771,25 +10733,9 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) } break; - case DB_IPCE_GET_THREAD_FOR_TASKID: - { - Thread *pThreadRet = NULL; - - // This is a synchronous event (reply required) - pEvent = m_pRCThread->GetIPCEventReceiveBuffer(); - - InitIPCReply(pEvent, DB_IPCE_GET_THREAD_FOR_TASKID_RESULT); - - pEvent->GetThreadForTaskIdResult.vmThreadToken.SetRawPtr(pThreadRet); - pEvent->hr = S_OK; - - m_pRCThread->SendIPCReply(); - } - break; - case DB_IPCE_CREATE_HANDLE: { - Object * pObject = (Object*)pEvent->CreateHandle.objectToken; + Object * pObject = (Object*)(CORDB_ADDRESS_TO_PTR(pEvent->CreateHandle.objectToken)); OBJECTREF objref = ObjectToOBJECTREF(pObject); AppDomain * pAppDomain = pEvent->vmAppDomain.GetRawPtr(); CorDebugHandleType handleType = pEvent->CreateHandle.handleType; @@ -10928,7 +10874,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmAssembly); Module * pModule = pDebuggerModule->GetRuntimeModule(); - bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0); + bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != (DWORD)0); mdMethodDef token = pEvent->SetJMCFunctionStatus.funcMetadataToken; @@ -11009,7 +10955,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) // Get data out of event DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmAssembly); - bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0); + bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != (DWORD)0); // Prepare reply pEvent = m_pRCThread->GetIPCEventReceiveBuffer(); @@ -11073,7 +11019,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) DebuggerIPCEvent * pResult = m_pRCThread->GetIPCEventReceiveBuffer(); InitIPCEvent(pResult, DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT, NULL); - pResult->MetadataUpdateRequest.pMetadataStart = pData; + pResult->MetadataUpdateRequest.pMetadataStart = (CORDB_ADDRESS)pData; pResult->MetadataUpdateRequest.nMetadataSize = countBytes; pResult->hr = hr; LOG((LF_CORDB, LL_INFO1000000, "D::HIPCE metadataStart=0x%x, nMetadataSize=0x%x\n", pData, countBytes)); @@ -11086,7 +11032,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) case DB_IPCE_RESOLVE_UPDATE_METADATA_2: { // Delete memory allocated with DB_IPCE_RESOLVE_UPDATE_METADATA_1. - BYTE * pData = (BYTE *) pEvent->MetadataUpdateRequest.pMetadataStart; + BYTE * pData = (BYTE *)(CORDB_ADDRESS_TO_PTR(pEvent->MetadataUpdateRequest.pMetadataStart)); DeleteInteropSafe(pData); DebuggerIPCEvent * pResult = m_pRCThread->GetIPCEventReceiveBuffer(); @@ -11718,7 +11664,7 @@ TypeHandle Debugger::TypeDataWalk::ReadTypeHandle() case ELEMENT_TYPE_SZARRAY: case ELEMENT_TYPE_PTR: case ELEMENT_TYPE_BYREF: - if(data->numTypeArgs == 1) + if(data->numTypeArgs == (UINT)1) { TypeHandle typar = ReadTypeHandle(); switch (et) @@ -11825,7 +11771,9 @@ HRESULT Debugger::GetAndSendBuffer(DebuggerRCThread* rcThread, ULONG bufSize) InitIPCEvent(event, DB_IPCE_GET_BUFFER_RESULT, NULL); // Allocate the buffer - event->GetBufferResult.hr = AllocateRemoteBuffer( bufSize, &event->GetBufferResult.pBuffer ); + void* pBuffer = NULL; + event->GetBufferResult.hr = AllocateRemoteBuffer( bufSize, &pBuffer ); + event->GetBufferResult.pBuffer = (CORDB_ADDRESS)pBuffer; // Send the result return rcThread->SendIPCReply(); @@ -13457,9 +13405,9 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, // Signal the RS to tell us what to do SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started.\n", tid)); SignalHijackStarted(); - SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started complete. DebugCounter=0x%x\n", tid, pFcd->debugCounter)); + SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started complete. DebugCounter=0x%x\n", tid, (UINT)const_cast&>(pFcd->debugCounter))); - if (pFcd->action == HIJACK_ACTION_WAIT) + if ((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_WAIT) { // This exception does NOT belong to the CLR. // If we belong to the CLR, then we either: @@ -13508,10 +13456,10 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, SPEW(fprintf(stderr, "0x%x D::FCHF: signaling HijackComplete.\n", tid)); SignalHijackComplete(); - SPEW(fprintf(stderr, "0x%x D::FCHF: done signaling HijackComplete. DebugCounter=0x%x\n", tid, pFcd->debugCounter)); + SPEW(fprintf(stderr, "0x%x D::FCHF: done signaling HijackComplete. DebugCounter=0x%x\n", tid, (UINT)const_cast&>(pFcd->debugCounter))); // we should know what we are about to do now - _ASSERTE(pFcd->action != HIJACK_ACTION_WAIT); + _ASSERTE((HijackAction)const_cast&>(pFcd->action) != HIJACK_ACTION_WAIT); // cleanup from above SPEW(fprintf(stderr, "0x%x D::FCHF: set debugger word = NULL.\n", tid)); @@ -13519,7 +13467,7 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, } // end can't stop region - if (pFcd->action == HIJACK_ACTION_EXIT_HANDLED) + if ((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_EXIT_HANDLED) { SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_EXECUTION\n", tid)); #if defined(OUT_OF_PROCESS_SETTHREADCONTEXT) && !defined(DACCESS_COMPILE) @@ -13533,7 +13481,7 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, else { SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_SEARCH\n", tid)); - _ASSERTE(pFcd->action == HIJACK_ACTION_EXIT_UNHANDLED); + _ASSERTE((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_EXIT_UNHANDLED); return EXCEPTION_CONTINUE_SEARCH; } } @@ -14017,76 +13965,12 @@ void Debugger::SendRawLogMessage( pThread); ipce->FirstLogMessage.iLevel = iLevel; - ipce->FirstLogMessage.szCategory.SetString(pCategory->GetUnicode()); - SetLSBufferFromSString(&ipce->FirstLogMessage.szContent, *pMessage); + ipce->FirstLogMessage.szCategory = PTR_TO_CORDB_ADDRESS(pCategory->GetUnicode()); + ipce->FirstLogMessage.szContent = PTR_TO_CORDB_ADDRESS(pMessage->GetUnicode()); m_pRCThread->SendIPCEvent(); } - -// This function sends a message to the right side informing it about -// the creation/modification of a LogSwitch -void Debugger::SendLogSwitchSetting(int iLevel, - int iReason, - _In_z_ LPCWSTR pLogSwitchName, - _In_z_ LPCWSTR pParentSwitchName) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - -#ifdef LOGGING - MAKE_UTF8PTR_FROMWIDE(pLogSwitchNameUtf8, pLogSwitchName); - MAKE_UTF8PTR_FROMWIDE(pParentSwitchNameUtf8, pParentSwitchName); - LOG((LF_CORDB, LL_INFO1000, "D::SLSS: Sending log switch message switch=%s parent=%s.\n", - pLogSwitchNameUtf8, pParentSwitchNameUtf8)); -#endif // LOGGING - - // Send the message only if the debugger is attached to this appdomain. - if (!CORDebuggerAttached()) - { - return; - } - - Thread *pThread = g_pEEInterface->GetThread(); - SENDIPCEVENT_BEGIN(this, pThread); - - if (CORDebuggerAttached()) - { - DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, - DB_IPCE_LOGSWITCH_SET_MESSAGE, - pThread); - - ipce->LogSwitchSettingMessage.iLevel = iLevel; - ipce->LogSwitchSettingMessage.iReason = iReason; - - - ipce->LogSwitchSettingMessage.szSwitchName.SetString(pLogSwitchName); - - if (pParentSwitchName == NULL) - { - pParentSwitchName = W(""); - } - - ipce->LogSwitchSettingMessage.szParentSwitchName.SetString(pParentSwitchName); - - m_pRCThread->SendIPCEvent(); - - // Stop all Runtime threads - TrapAllRuntimeThreads(); - } - else - { - LOG((LF_CORDB,LL_INFO1000, "D::SLSS: Skipping SendIPCEvent because RS detached.")); - } - - SENDIPCEVENT_END; -} - // send a custom debugger notification to the RS // Arguments: // input: pThread - thread on which the notification occurred @@ -15102,130 +14986,6 @@ BOOL Debugger::IsThreadContextInvalid(Thread *pThread, CONTEXT *pCtx) return invalid; } - -// notification when a SQL connection begins -void Debugger::CreateConnection(CONNID dwConnectionId, _In_z_ WCHAR *wzName) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - LOG((LF_CORDB,LL_INFO1000, "D::CreateConnection %d\n.", dwConnectionId)); - - if (CORDBUnrecoverableError(this)) - return; - - Thread *pThread = g_pEEInterface->GetThread(); - SENDIPCEVENT_BEGIN(this, pThread); - - if (CORDebuggerAttached()) - { - DebuggerIPCEvent* ipce; - - // Send a update module syns event to the Right Side. - ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, DB_IPCE_CREATE_CONNECTION, - pThread); - ipce->CreateConnection.connectionId = dwConnectionId; - _ASSERTE(wzName != NULL); - ipce->CreateConnection.wzConnectionName.SetString(wzName); - - m_pRCThread->SendIPCEvent(); - } - else - { - LOG((LF_CORDB,LL_INFO1000, "D::CreateConnection: Skipping SendIPCEvent because RS detached.")); - } - - // Stop all Runtime threads if we actually sent an event - if (CORDebuggerAttached()) - { - TrapAllRuntimeThreads(); - } - - SENDIPCEVENT_END; -} - -// notification when a SQL connection ends -void Debugger::DestroyConnection(CONNID dwConnectionId) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - LOG((LF_CORDB,LL_INFO1000, "D::DestroyConnection %d\n.", dwConnectionId)); - - if (CORDBUnrecoverableError(this)) - return; - - Thread *thread = g_pEEInterface->GetThread(); - // Note that the debugger lock is reentrant, so we may or may not hold it already. - SENDIPCEVENT_BEGIN(this, thread); - - // Send a update module syns event to the Right Side. - DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, DB_IPCE_DESTROY_CONNECTION, - thread); - ipce->ConnectionChange.connectionId = dwConnectionId; - - // IPC event is now initialized, so we can send it over. - SendSimpleIPCEventAndBlock(); - - // This will block on the continue - SENDIPCEVENT_END; - -} - -// notification for SQL connection changes -void Debugger::ChangeConnection(CONNID dwConnectionId) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - LOG((LF_CORDB,LL_INFO1000, "D::ChangeConnection %d\n.", dwConnectionId)); - - if (CORDBUnrecoverableError(this)) - return; - - Thread *pThread = g_pEEInterface->GetThread(); - SENDIPCEVENT_BEGIN(this, pThread); - - if (CORDebuggerAttached()) - { - DebuggerIPCEvent* ipce; - - // Send a update module syns event to the Right Side. - ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, DB_IPCE_CHANGE_CONNECTION, - pThread); - ipce->ConnectionChange.connectionId = dwConnectionId; - m_pRCThread->SendIPCEvent(); - } - else - { - LOG((LF_CORDB,LL_INFO1000, "D::ChangeConnection: Skipping SendIPCEvent because RS detached.")); - } - - // Stop all Runtime threads if we actually sent an event - if (CORDebuggerAttached()) - { - TrapAllRuntimeThreads(); - } - - SENDIPCEVENT_END; -} - - // // Are we the helper thread? // Some important things about running on the helper thread: diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 20139885d95316..2a0543929969c6 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -776,8 +776,6 @@ class DebuggerRCThread #endif _ASSERTE(m_pDCB != NULL); - // In case this turns into a continuation event - GetRCThreadSendBuffer()->next = NULL; LOG((LF_CORDB,LL_EVERYTHING, "GIPCESBuffer: got event %p\n", GetRCThreadSendBuffer())); return GetRCThreadSendBuffer(); @@ -2133,15 +2131,6 @@ class Debugger : public DebugInterface HRESULT GetAndSendInterceptCommand(DebuggerIPCEvent *event); - //HRESULT GetAndSendJITFunctionData(DebuggerRCThread* rcThread, - // mdMethodDef methodToken, - // void* functionModuleToken); - HRESULT GetFuncData(mdMethodDef funcMetadataToken, - DebuggerModule* pDebuggerModule, - SIZE_T nVersion, - DebuggerIPCE_FuncData *data); - - // The following four functions convert between type handles and the data that is // shipped for types to and from the right-side. // @@ -2200,12 +2189,6 @@ class Debugger : public DebugInterface }; - - - HRESULT GetMethodDescData(MethodDesc *pFD, - DebuggerJitInfo *pJITInfo, - DebuggerIPCE_JITFuncData *data); - void GetAndSendTransitionStubInfo(CORDB_ADDRESS_TYPE *stubAddress); void SendBreakpoint(Thread *thread, T_CONTEXT *context, @@ -2484,11 +2467,6 @@ class Debugger : public DebugInterface SString * pSwitchName, SString * pMessage); - void SendLogSwitchSetting (int iLevel, - int iReason, - _In_z_ LPCWSTR pLogSwitchName, - _In_z_ LPCWSTR pParentSwitchName); - bool IsLoggingEnabled (void) { LIMITED_METHOD_CONTRACT; @@ -2558,11 +2536,6 @@ class Debugger : public DebugInterface BOOL IsThreadContextInvalid(Thread *pThread, T_CONTEXT *pCtx); - // notification for SQL fiber debugging support - void CreateConnection(CONNID dwConnectionId, _In_z_ WCHAR *wzName); - void DestroyConnection(CONNID dwConnectionId); - void ChangeConnection(CONNID dwConnectionId); - // // This function is used to identify the helper thread. // @@ -3525,10 +3498,10 @@ class DebuggerEval DebuggerIPCE_FuncEvalArgData *argData = GetArgData(); for (unsigned int i = 0; i < m_argCount; i++) { - if (argData[i].fullArgType != NULL) + if (argData[i].fullArgType != (CORDB_ADDRESS)0) { _ASSERTE(g_pDebugger != NULL); - g_pDebugger->ReleaseRemoteBuffer((BYTE*)argData[i].fullArgType, true); + g_pDebugger->ReleaseRemoteBuffer((BYTE*)(CORDB_ADDRESS)argData[i].fullArgType, true); } } diff --git a/src/coreclr/debug/ee/funceval.cpp b/src/coreclr/debug/ee/funceval.cpp index d40c71c6d4daff..5a402cd640df2a 100644 --- a/src/coreclr/debug/ee/funceval.cpp +++ b/src/coreclr/debug/ee/funceval.cpp @@ -258,7 +258,7 @@ static void ValidateFuncEvalReturnType(DebuggerIPCE_FuncEvalType evalType, Metho // // Given a register, return the value. // -static SIZE_T GetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *regAddr, SIZE_T regValue) +static SIZE_T GetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, CORDB_ADDRESS regAddr, ULONG64 regValue) { LIMITED_METHOD_CONTRACT; @@ -267,9 +267,9 @@ static SIZE_T GetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *re // Check whether the register address is the marker value for a register in a non-leaf frame. // This is related to the funceval breaking change. // - if (regAddr == CORDB_ADDRESS_TO_PTR(kNonLeafFrameRegAddr)) + if (regAddr == kNonLeafFrameRegAddr) { - ret = regValue; + ret = (SIZE_T)regValue; } else { @@ -472,7 +472,7 @@ static SIZE_T GetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *re // // Given a register, set its value. // -static void SetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *regAddr, SIZE_T newValue) +static void SetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, CORDB_ADDRESS regAddr, SIZE_T newValue) { CONTRACTL { @@ -482,7 +482,7 @@ static void SetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *regA // Check whether the register address is the marker value for a register in a non-leaf frame. // If so, then we can't update the register. Throw an exception to communicate this error. - if (regAddr == CORDB_ADDRESS_TO_PTR(kNonLeafFrameRegAddr)) + if (regAddr == kNonLeafFrameRegAddr) { COMPlusThrowHR(CORDBG_E_FUNC_EVAL_CANNOT_UPDATE_REGISTER_IN_NONLEAF_FRAME); return; @@ -1444,7 +1444,7 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, // we need to GC protect their addresses as well. if (pFEAD->argAddr != NULL) { - pByRefMaybeInteriorPtrArray[currArgIndex] = pFEAD->argAddr; + pByRefMaybeInteriorPtrArray[currArgIndex] = CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); } switch (pFEAD->argElementType) @@ -1822,7 +1822,7 @@ void BoxFuncEvalThisParameter(DebuggerEval *pDE, // // A buffer should have been allocated for the full struct type _ASSERTE(argData[0].fullArgType != NULL); - Debugger::TypeDataWalk walk((DebuggerIPCE_TypeArgData *) argData[0].fullArgType, argData[0].fullArgTypeNodeCount); + Debugger::TypeDataWalk walk((DebuggerIPCE_TypeArgData *) CORDB_ADDRESS_TO_PTR(argData[0].fullArgType), argData[0].fullArgTypeNodeCount); TypeHandle typeHandle = walk.ReadTypeHandle(); @@ -2509,7 +2509,7 @@ void CopyArgsToBuffer(DebuggerEval *pDE, else { GetAndSetLiteralValue(pDest, pFEArgInfo[currArgIndex].argSigType, - pFEAD->argAddr, pFEAD->argElementType); + CORDB_ADDRESS_TO_PTR(pFEAD->argAddr), pFEAD->argElementType); } #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) @@ -2533,7 +2533,7 @@ void CopyArgsToBuffer(DebuggerEval *pDE, // be bashing memory right next to the source value as the function being called acts upon some // bigger value. GetAndSetLiteralValue(pDest, pFEArgInfo[currArgIndex].byrefArgSigType, - pFEAD->argAddr, pFEAD->argElementType); + CORDB_ADDRESS_TO_PTR(pFEAD->argAddr), pFEAD->argElementType); } #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) @@ -2566,7 +2566,7 @@ void CopyArgsToBuffer(DebuggerEval *pDE, CorElementType relevantType = (isByRef ? pFEArgInfo[currArgIndex].byrefArgSigType : pFEArgInfo[currArgIndex].argSigType); - GetAndSetLiteralValue(pDest, relevantType, pFEAD->argLiteralData, pFEAD->argElementType); + GetAndSetLiteralValue(pDest, relevantType, CORDB_ADDRESS_TO_PTR(pFEAD->argLiteralData), pFEAD->argElementType); #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) { diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 5affc01830077a..7c973afd5d0ccc 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -377,10 +377,10 @@ class MSLAYOUT GeneralLsPointer { protected: friend ULONG_PTR LsPtrToCookie(GeneralLsPointer p); - void * m_ptr; + Portable m_ptr; public: - bool IsNull() { return m_ptr == NULL; } + bool IsNull() { return m_ptr == (CORDB_ADDRESS)0; } }; class MSLAYOUT GeneralRsPointer @@ -394,7 +394,7 @@ class MSLAYOUT GeneralRsPointer // In some cases, we need to get a uuid from a pointer (ie, in a hash) inline ULONG_PTR LsPtrToCookie(GeneralLsPointer p) { - return (ULONG_PTR) p.m_ptr; + return (ULONG_PTR)(CORDB_ADDRESS)p.m_ptr; } #define VmPtrToCookie(vm) LsPtrToCookie((vm).ToLsPtr()) @@ -414,11 +414,11 @@ class MSLAYOUT LsPointer : public GeneralLsPointer public: void Set(void * p) { - m_ptr = p; + m_ptr = PTR_TO_CORDB_ADDRESS(p); } void * UnsafeGet() { - return m_ptr; + return CORDB_ADDRESS_TO_PTR((CORDB_ADDRESS)m_ptr); } static LsPointer NullPtr() @@ -433,8 +433,8 @@ class MSLAYOUT LsPointer : public GeneralLsPointer return t; } - bool operator!= (void * p) { return m_ptr != p; } - bool operator== (void * p) { return m_ptr == p; } + bool operator!= (void * p) { return (CORDB_ADDRESS)m_ptr != PTR_TO_CORDB_ADDRESS(p); } + bool operator== (void * p) { return (CORDB_ADDRESS)m_ptr == PTR_TO_CORDB_ADDRESS(p); } bool operator==(LsPointer p) { return p.m_ptr == this->m_ptr; } // We should never UnWrap() them in the RS, so we don't define that here. @@ -525,8 +525,8 @@ class MSLAYOUT LsPointer : public GeneralLsPointer return t; } - bool operator!= (void * p) { return m_ptr != p; } - bool operator== (void * p) { return m_ptr == p; } + bool operator!= (void * p) { return (CORDB_ADDRESS)m_ptr != PTR_TO_CORDB_ADDRESS(p); } + bool operator== (void * p) { return (CORDB_ADDRESS)m_ptr == PTR_TO_CORDB_ADDRESS(p); } bool operator==(LsPointer p) { return p.m_ptr == this->m_ptr; } // @todo - we want to be able to swap out Set + Unwrap functions @@ -534,13 +534,13 @@ class MSLAYOUT LsPointer : public GeneralLsPointer { SUPPORTS_DAC; // We could validate the pointer here. - m_ptr = p; + m_ptr = PTR_TO_CORDB_ADDRESS(p); } T * UnWrap() { // If we wanted to validate the pointer, here's our chance. - return static_cast(m_ptr); + return reinterpret_cast(CORDB_ADDRESS_TO_PTR((CORDB_ADDRESS)m_ptr)); } }; @@ -570,12 +570,6 @@ class MSLAYOUT RsPointer : public GeneralRsPointer #endif // !RIGHT_SIDE_COMPILE -// We must be binary compatible w/ a pointer. -static_assert(sizeof(LsPointer) == sizeof(GeneralLsPointer)); - -static_assert(sizeof(void*) == sizeof(GeneralLsPointer)); - - //----------------------------------------------------------------------------- // Definitions for Left-Side ptrs. @@ -649,7 +643,7 @@ class MSLAYOUT VMPTR_Base // - In DAC: must be marshalled to a host-pointer and then they can be used via DAC // - In RS: opaque handles. private: - TADDR m_addr; + Portable m_addr; public: typedef VMPTR_Base VMPTR_This; @@ -665,7 +659,7 @@ class MSLAYOUT VMPTR_Base TDacPtr GetDacPtr() const { SUPPORTS_DAC; - return TDacPtr(m_addr); + return TDacPtr((TADDR)m_addr); } @@ -675,13 +669,13 @@ class MSLAYOUT VMPTR_Base void SetDacTargetPtr(TADDR addr) { SUPPORTS_DAC; - m_addr = addr; + m_addr = (CORDB_ADDRESS)addr; } void SetHostPtr(const TTargetPtr * pObject) { SUPPORTS_DAC; - m_addr = PTR_HOST_TO_TADDR(pObject); + m_addr = (CORDB_ADDRESS)PTR_HOST_TO_TADDR(pObject); } @@ -695,7 +689,7 @@ class MSLAYOUT VMPTR_Base // This is commonly used by the Left-side to create a VMPTR_ for a notification event. void SetRawPtr(TTargetPtr * ptr) { - m_addr = reinterpret_cast(ptr); + m_addr = PTR_TO_CORDB_ADDRESS(ptr); } // This will get the raw underlying target pointer. @@ -703,7 +697,7 @@ class MSLAYOUT VMPTR_Base // hijack or in-proc worker threads) TTargetPtr * GetRawPtr() { - return reinterpret_cast(m_addr); + return reinterpret_cast((TADDR)m_addr); } // Convenience for converting TTargetPtr --> VMPTR @@ -729,21 +723,21 @@ class MSLAYOUT VMPTR_Base // @dbgtodo inspection: LSPTRs will go away entirely once we've moved completely over to DAC LsPointer ToLsPtr() { - return LsPointer::MakePtr( reinterpret_cast(m_addr)); + return LsPointer::MakePtr( reinterpret_cast((TADDR)m_addr)); } #endif // // Operators to emulate Pointer semantics. // - bool IsNull() { SUPPORTS_DAC; return m_addr == (TADDR)0; } + bool IsNull() { SUPPORTS_DAC; return m_addr == (CORDB_ADDRESS)0; } static VMPTR_This NullPtr() { SUPPORTS_DAC; VMPTR_This dummy; - dummy.m_addr = (TADDR)NULL; + dummy.m_addr = (CORDB_ADDRESS)NULL; return dummy; } @@ -1263,7 +1257,6 @@ inline bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2) return !IsCloserToLeaf(fp1, fp2); } - // struct DebuggerIPCE_FuncData: DebuggerIPCE_FuncData holds data // to describe a given function, its // class, and a little bit about the code for the function. This is used @@ -1462,8 +1455,8 @@ struct MSLAYOUT DebuggerIPCE_STRData struct MSLAYOUT DebuggerIPCE_BasicTypeData { - CorElementType elementType; - mdTypeDef metadataToken; + Portable elementType; + Portable metadataToken; VMPTR_Assembly vmAssembly; VMPTR_TypeHandle vmTypeHandle; }; @@ -1489,7 +1482,7 @@ struct MSLAYOUT DebuggerIPCE_BasicTypeData // struct MSLAYOUT DebuggerIPCE_ExpandedTypeData { - CorElementType elementType; // Note this is _never_ E_T_VAR, E_T_WITH or E_T_MVAR + Portable elementType; // Note this is _never_ E_T_VAR, E_T_WITH or E_T_MVAR union MSLAYOUT { // used for E_T_CLASS and E_T_VALUECLASS, E_T_PTR, E_T_BYREF etc. @@ -1497,15 +1490,15 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData // For constructed E_T_CLASS or E_T_VALUECLASS the tokens will be set and the typeHandle will be non-NULL // For E_T_PTR etc. the tokens will be NULL and the typeHandle will be non-NULL. struct MSLAYOUT - { - mdTypeDef metadataToken; - VMPTR_Assembly vmAssembly; + { + Portable metadataToken; + VMPTR_Assembly vmAssembly; VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments } ClassTypeData; // used for E_T_PTR, E_T_BYREF etc. struct MSLAYOUT - { + { DebuggerIPCE_BasicTypeData unaryTypeArg; // used only when sending back to debugger } UnaryTypeData; @@ -1513,13 +1506,13 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData // used for E_T_ARRAY etc. struct MSLAYOUT { - DebuggerIPCE_BasicTypeData arrayTypeArg; // used only when sending back to debugger - DWORD arrayRank; + DebuggerIPCE_BasicTypeData arrayTypeArg; // used only when sending back to debugger + Portable arrayRank; } ArrayTypeData; // used for E_T_FNPTR struct MSLAYOUT - { + { VMPTR_TypeHandle typeHandle; // if non-null then further fetches needed to get type arguments } NaryTypeData; @@ -1536,8 +1529,8 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData // flattened type argument data. struct MSLAYOUT DebuggerIPCE_TypeArgData { - DebuggerIPCE_ExpandedTypeData data; - unsigned int numTypeArgs; // number of immediate children on the type tree + DebuggerIPCE_ExpandedTypeData data; + Portable numTypeArgs; // number of immediate children on the type tree }; @@ -1605,24 +1598,22 @@ const CORDB_ADDRESS kNonLeafFrameRegAddr = (CORDB_ADDRESS)(-1); struct MSLAYOUT RemoteAddress { - RemoteAddressKind kind; - void *frame; - - CorDebugRegister reg1; - void *reg1Addr; - SIZE_T reg1Value; // this is the actual value of the register + Portable kind; + Portable reg1; + Portable reg1Addr; + Portable reg1Value; // this is the actual value of the register union MSLAYOUT { struct MSLAYOUT { - CorDebugRegister reg2; - void *reg2Addr; - SIZE_T reg2Value; // this is the actual value of the register + Portable reg2; + Portable reg2Addr; + Portable reg2Value; // this is the actual value of the register } u; - CORDB_ADDRESS addr; - DWORD floatIndex; + Portable addr; + Portable floatIndex; }; }; @@ -1652,14 +1643,14 @@ enum NameChangeType // struct MSLAYOUT DebuggerIPCE_FuncEvalArgData { - RemoteAddress argHome; // enregistered variable home - void *argAddr; // address if not enregistered - CorElementType argElementType; - unsigned int fullArgTypeNodeCount; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) - void *fullArgType; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) - BYTE argLiteralData[8]; // copy of generic value data - bool argIsLiteral; // true if value is in argLiteralData - bool argIsHandleValue; // true if argAddr is OBJECTHANDLE + RemoteAddress argHome; // enregistered variable home + CORDB_ADDRESS argAddr; // address if not enregistered + Portable argElementType; + Portable fullArgTypeNodeCount; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) + Portable fullArgType; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) + Portable argLiteralData[8]; // copy of generic value data + Portable argIsLiteral; // true if value is in argLiteralData + Portable argIsHandleValue; // true if argAddr is OBJECTHANDLE }; @@ -1669,21 +1660,19 @@ struct MSLAYOUT DebuggerIPCE_FuncEvalArgData // struct MSLAYOUT DebuggerIPCE_FuncEvalInfo { - VMPTR_Thread vmThreadToken; - DebuggerIPCE_FuncEvalType funcEvalType; - mdMethodDef funcMetadataToken; - mdTypeDef funcClassMetadataToken; - VMPTR_Assembly vmAssembly; - RSPTR_CORDBEVAL funcEvalKey; - bool evalDuringException; - - unsigned int argCount; - unsigned int genericArgsCount; - unsigned int genericArgsNodeCount; - - SIZE_T stringSize; - - SIZE_T arrayRank; + VMPTR_Thread vmThreadToken; + Portable funcEvalType; + Portable funcMetadataToken; + Portable funcClassMetadataToken; + VMPTR_Assembly vmAssembly; + RSPTR_CORDBEVAL funcEvalKey; + Portable evalDuringException; + + Portable argCount; + Portable genericArgsCount; + Portable genericArgsNodeCount; + Portable stringSize; + Portable arrayRank; }; @@ -1703,23 +1692,11 @@ enum HijackAction // struct MSLAYOUT DebuggerIPCFirstChanceData { - LSPTR_CONTEXT pLeftSideContext; - HijackAction action; - UINT debugCounter; + LSPTR_CONTEXT pLeftSideContext; + Portable action; + Portable debugCounter; }; -// -// DebuggerIPCSecondChanceData holds info communicated from the RS -// to the LS when setting up a second chance exception hijack. This is -// used when Win32 debugging only. -// -struct MSLAYOUT DebuggerIPCSecondChanceData -{ - DT_CONTEXT threadContext; -}; - - - //----------------------------------------------------------------------------- // This struct holds pointer from the LS and needs to copy to // the RS. We have to free the memory on the RS. @@ -1831,17 +1808,6 @@ struct MSLAYOUT Ls_Rs_StringBuffer : public Ls_Rs_BaseBuffer }; -// Data for an Managed Debug Assistant Probe (MDA). -struct MSLAYOUT DebuggerMDANotification -{ - Ls_Rs_StringBuffer szName; - Ls_Rs_StringBuffer szDescription; - Ls_Rs_StringBuffer szXml; - DWORD dwOSThreadId; - CorDebugMDAFlags flags; -}; - - // The only remaining problem is that register number mappings are different for each platform. It turns out // that the debugger only uses REGNUM_SP and REGNUM_AMBIENT_SP though, so we can just virtualize these two for // the target platform. @@ -1905,25 +1871,18 @@ static_assert(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP); // struct MSLAYOUT DebuggerIPCEvent { - DebuggerIPCEvent* next; - DebuggerIPCEventType type; - DWORD processId; - DWORD threadId; - VMPTR_AppDomain vmAppDomain; - VMPTR_Thread vmThread; + Portable type; + Portable processId; + Portable threadId; + VMPTR_AppDomain vmAppDomain; + VMPTR_Thread vmThread; - HRESULT hr; - bool replyRequired; - bool asyncSend; + Portable hr; + Portable replyRequired; + Portable asyncSend; union MSLAYOUT { - struct MSLAYOUT - { - // Pointer to a BOOL in the target. - CORDB_ADDRESS pfBeingDebugged; - } LeftSideStartupData; - struct MSLAYOUT { // Module whose metadata is being updated @@ -1965,37 +1924,35 @@ struct MSLAYOUT DebuggerIPCEvent VMPTR_Assembly vmAssembly; } UpdateModuleSymsData; - DebuggerMDANotification MDANotification; - struct MSLAYOUT { LSPTR_BREAKPOINT breakpointToken; - mdMethodDef funcMetadataToken; + Portable funcMetadataToken; VMPTR_Assembly vmAssembly; - bool isIL; - SIZE_T offset; - SIZE_T encVersion; - LSPTR_METHODDESC nativeCodeMethodDescToken; // points to the MethodDesc if !isIL - CORDB_ADDRESS codeStartAddress; + Portable isIL; + Portable offset; + Portable encVersion; + LSPTR_METHODDESC nativeCodeMethodDescToken; // points to the MethodDesc if !isIL + Portable codeStartAddress; } BreakpointData; struct MSLAYOUT { - mdMethodDef funcMetadataToken; + Portable funcMetadataToken; VMPTR_Module pModule; } DisableOptData; struct MSLAYOUT { - BOOL enableEvents; + Portable enableEvents; VMPTR_Object vmObj; } ForceCatchHandlerFoundData; struct MSLAYOUT { VMPTR_Module vmModule; - mdTypeDef classMetadataToken; - BOOL Enabled; + Portable classMetadataToken; + Portable Enabled; } CustomNotificationData; struct MSLAYOUT @@ -2005,96 +1962,77 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { -#ifdef FEATURE_DATABREAKPOINT + Portable contextSize; CONTEXT context; -#else - int dummy; -#endif } DataBreakpointData; struct MSLAYOUT { - LSPTR_STEPPER stepperToken; - VMPTR_Thread vmThreadToken; - FramePointer frameToken; - bool stepIn; - bool rangeIL; - bool IsJMCStop; - unsigned int totalRangeCount; - CorDebugStepReason reason; - CorDebugUnmappedStop rgfMappingStop; - CorDebugIntercept rgfInterceptStop; - unsigned int rangeCount; + LSPTR_STEPPER stepperToken; + VMPTR_Thread vmThreadToken; + FramePointer frameToken; + Portable stepIn; + Portable rangeIL; + Portable IsJMCStop; + Portable totalRangeCount; + Portable reason; + Portable rgfMappingStop; + Portable rgfInterceptStop; + Portable rangeCount; COR_DEBUG_STEP_RANGE range; //note that this is an array } StepData; - struct MSLAYOUT - { - // An unvalidated GC-handle - VMPTR_OBJECTHANDLE GCHandle; - } GetGCHandleInfo; - - struct MSLAYOUT - { - // An unvalidated GC-handle for which we're returning the results - LSPTR_OBJECTHANDLE GCHandle; - - // The following are initialized by the LS in response to our query: - VMPTR_AppDomain vmAppDomain; // AD that handle is in (only applicable if fValid). - bool fValid; // Did the LS determine the GC handle to be valid? - } GetGCHandleInfoResult; - // Allocate memory on the left-side struct MSLAYOUT { - ULONG bufSize; // number of bytes to allocate + Portable bufSize; // number of bytes to allocate } GetBuffer; // Memory allocated on the left-side struct MSLAYOUT { - void *pBuffer; // LS pointer to the buffer allocated - HRESULT hr; // success / failure + Portable pBuffer; // LS pointer to the buffer allocated + Portable hr; // success / failure } GetBufferResult; // Free a buffer allocated on the left-side with GetBuffer struct MSLAYOUT { - void *pBuffer; // Pointer previously returned in GetBufferResult + Portable pBuffer; // Pointer previously returned in GetBufferResult } ReleaseBuffer; struct MSLAYOUT { - HRESULT hr; + Portable hr; } ReleaseBufferResult; // Apply an EnC edit struct MSLAYOUT { - VMPTR_Assembly vmAssembly; // Module to edit - DWORD cbDeltaMetadata; // size of blob pointed to by pDeltaMetadata - CORDB_ADDRESS pDeltaMetadata; // pointer to delta metadata in debuggee - // it's the RS's responsibility to allocate and free - // this (and pDeltaIL) using GetBuffer / ReleaseBuffer - CORDB_ADDRESS pDeltaIL; // pointer to delta IL in debugee - DWORD cbDeltaIL; // size of blob pointed to by pDeltaIL + VMPTR_Assembly vmAssembly; // Module to edit + Portable cbDeltaMetadata; // size of blob pointed to by pDeltaMetadata + Portable pDeltaMetadata; // pointer to delta metadata in debuggee + // it's the RS's responsibility to allocate and free + // this (and pDeltaIL) using GetBuffer / ReleaseBuffer + Portable pDeltaIL; // pointer to delta IL in debugee + Portable cbDeltaIL; // size of blob pointed to by pDeltaIL } ApplyChanges; struct MSLAYOUT { - HRESULT hr; + Portable hr; } ApplyChangesResult; struct MSLAYOUT { - mdTypeDef classMetadataToken; + Portable classMetadataToken; VMPTR_Assembly vmAssembly; LSPTR_ASSEMBLY classDebuggerAssemblyToken; } LoadClass; struct MSLAYOUT { - mdTypeDef classMetadataToken; + Portable classMetadataToken; VMPTR_Assembly vmAssembly; LSPTR_ASSEMBLY classDebuggerAssemblyToken; } UnloadClass; @@ -2102,59 +2040,54 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { VMPTR_Assembly vmAssembly; - bool flag; + Portable flag; } SetClassLoad; struct MSLAYOUT { VMPTR_OBJECTHANDLE vmExceptionHandle; - bool firstChance; - bool continuable; + Portable firstChance; + Portable continuable; } Exception; struct MSLAYOUT { - VMPTR_Thread vmThreadToken; + VMPTR_Thread vmThreadToken; } ClearException; struct MSLAYOUT { - void *address; + Portable address; } IsTransitionStub; struct MSLAYOUT { - bool isStub; + Portable isStub; } IsTransitionStubResult; struct MSLAYOUT { - CORDB_ADDRESS startAddress; - bool fCanSetIPOnly; - VMPTR_Thread vmThreadToken; + Portable startAddress; + Portable fCanSetIPOnly; + VMPTR_Thread vmThreadToken; VMPTR_Assembly vmAssembly; - mdMethodDef mdMethod; + Portable mdMethod; VMPTR_MethodDesc vmMethodDesc; - SIZE_T offset; - bool fIsIL; - void * firstExceptionHandler; + Portable offset; + Portable fIsIL; } SetIP; // this is also used for CanSetIP struct MSLAYOUT { int iLevel; - EmbeddedIPCString szCategory; - Ls_Rs_StringBuffer szContent; + Portable szCategory; + Portable szContent; } FirstLogMessage; struct MSLAYOUT { - int iLevel; - int iReason; - - EmbeddedIPCString szSwitchName; - EmbeddedIPCString szParentSwitchName; + Portable iLevel; } LogSwitchSettingMessage; // information needed to send to the RS as part of a custom notification from the target @@ -2164,29 +2097,29 @@ struct MSLAYOUT DebuggerIPCEvent VMPTR_Assembly vmAssembly; // metadata token for the type of the CustomNotification object's type - mdTypeDef classToken; + Portable classToken; } CustomNotification; struct MSLAYOUT { VMPTR_Thread vmThreadToken; - CorDebugThreadState debugState; + Portable debugState; } SetAllDebugState; DebuggerIPCE_FuncEvalInfo FuncEval; struct MSLAYOUT { - CORDB_ADDRESS argDataArea; + Portable argDataArea; LSPTR_DEBUGGEREVAL debuggerEvalKey; } FuncEvalSetupComplete; struct MSLAYOUT { RSPTR_CORDBEVAL funcEvalKey; - bool successful; - bool aborted; - void *resultAddr; + Portable successful; + Portable aborted; + Portable resultAddr; // AppDomain that the result is in. VMPTR_AppDomain vmAppDomain; @@ -2212,42 +2145,35 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - void *objectRefAddress; + Portable objectRefAddress; VMPTR_OBJECTHANDLE vmObjectHandle; - void *newReference; + Portable newReference; } SetReference; struct MSLAYOUT { - NameChangeType eventType; + Portable eventType; VMPTR_AppDomain vmAppDomain; - VMPTR_Thread vmThread; + VMPTR_Thread vmThread; } NameChange; - struct MSLAYOUT - { - VMPTR_Assembly vmAssembly; - BOOL fAllowJitOpts; - BOOL fEnableEnC; - } JitDebugInfo; - // EnC Remap opportunity struct MSLAYOUT { VMPTR_Assembly vmAssembly; - mdMethodDef funcMetadataToken ; // methodDef of function with remap opportunity - SIZE_T currentVersionNumber; // version currently executing - SIZE_T resumeVersionNumber; // latest version - SIZE_T currentILOffset; // the IL offset of the current IP - SIZE_T *resumeILOffset; // pointer into left-side where an offset to resume - // to should be written if remap is desired. + Portable funcMetadataToken; // methodDef of function with remap opportunity + Portable currentVersionNumber; // version currently executing + Portable resumeVersionNumber; // latest version + Portable currentILOffset; // the IL offset of the current IP + Portable resumeILOffset; // pointer into left-side where an offset to resume + // to should be written if remap is desired. } EnCRemap; // EnC Remap has taken place struct MSLAYOUT { VMPTR_Assembly vmAssembly; - mdMethodDef funcMetadataToken; // methodDef of function that was remapped + Portable funcMetadataToken; // methodDef of function that was remapped } EnCRemapComplete; // Notification that the LS is about to update a CLR data structure to account for a @@ -2255,17 +2181,17 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { VMPTR_Assembly vmAssembly; - mdToken memberMetadataToken; // Either a methodDef token indicating the function that - // was updated/added, or a fieldDef token indicating the - // field which was added. - mdTypeDef classMetadataToken; // TypeDef token of the class in which the update was made - SIZE_T newVersionNumber; // The new function/module version + Portable memberMetadataToken; // Either a methodDef token indicating the function that + // was updated/added, or a fieldDef token indicating the + // field which was added. + Portable classMetadataToken; // TypeDef token of the class in which the update was made + Portable newVersionNumber; // The new function/module version } EnCUpdate; struct MSLAYOUT { - void *oldData; - void *newData; + Portable oldData; + Portable newData; DebuggerIPCE_BasicTypeData type; } SetValueClass; @@ -2276,35 +2202,14 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { VMPTR_Assembly vmAssembly; - mdMethodDef funcMetadataToken; - DWORD dwStatus; + Portable funcMetadataToken; + Portable dwStatus; } SetJMCFunctionStatus; struct MSLAYOUT { - TASKID taskid; - } GetThreadForTaskId; - - struct MSLAYOUT - { - VMPTR_Thread vmThreadToken; - } GetThreadForTaskIdResult; - - struct MSLAYOUT - { - CONNID connectionId; - } ConnectionChange; - - struct MSLAYOUT - { - CONNID connectionId; - EmbeddedIPCString wzConnectionName; - } CreateConnection; - - struct MSLAYOUT - { - void *objectToken; - CorDebugHandleType handleType; + Portable objectToken; + Portable handleType; } CreateHandle; struct MSLAYOUT @@ -2316,22 +2221,22 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { VMPTR_OBJECTHANDLE vmObjectHandle; - CorDebugHandleType handleType; + Portable handleType; } DisposeHandle; struct MSLAYOUT { - FramePointer framePointer; - SIZE_T nOffset; - CorDebugExceptionCallbackType eventType; - DWORD dwFlags; - VMPTR_OBJECTHANDLE vmExceptionHandle; + FramePointer framePointer; + Portable nOffset; + Portable eventType; + Portable dwFlags; + VMPTR_OBJECTHANDLE vmExceptionHandle; } ExceptionCallback2; struct MSLAYOUT { - CorDebugExceptionUnwindCallbackType eventType; - DWORD dwFlags; + Portable eventType; + Portable dwFlags; } ExceptionUnwind; struct MSLAYOUT @@ -2343,8 +2248,8 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { VMPTR_Module vmModule; - void * pMetadataStart; - ULONG nMetadataSize; + Portable pMetadataStart; + Portable nMetadataSize; } MetadataUpdateRequest; }; }; diff --git a/src/coreclr/debug/inc/dbgipceventtypes.h b/src/coreclr/debug/inc/dbgipceventtypes.h index 3e0ff8df70e9f8..43411e02cd2bf8 100644 --- a/src/coreclr/debug/inc/dbgipceventtypes.h +++ b/src/coreclr/debug/inc/dbgipceventtypes.h @@ -44,7 +44,6 @@ IPC_EVENT_TYPE1(DB_IPCE_USER_BREAKPOINT ,0x011C) IPC_EVENT_TYPE1(DB_IPCE_FIRST_LOG_MESSAGE ,0x011D) // DB_IPCE_CONTINUED_LOG_MESSAGE = 0x11E, used to be here in v1.1, // But we've removed that remove the v2.0 protocol -IPC_EVENT_TYPE1(DB_IPCE_LOGSWITCH_SET_MESSAGE ,0x011F) IPC_EVENT_TYPE1(DB_IPCE_CREATE_APP_DOMAIN ,0x0120) // IPC_EVENT_TYPE1(DB_IPCE_EXIT_APP_DOMAIN ,0x0121) IPC_EVENT_TYPE1(DB_IPCE_LOAD_ASSEMBLY ,0x0122) @@ -53,7 +52,6 @@ IPC_EVENT_TYPE1(DB_IPCE_SET_DEBUG_STATE_RESULT ,0x0124) IPC_EVENT_TYPE1(DB_IPCE_FUNC_EVAL_SETUP_RESULT ,0x0125) IPC_EVENT_TYPE1(DB_IPCE_FUNC_EVAL_COMPLETE ,0x0126) IPC_EVENT_TYPE1(DB_IPCE_SET_REFERENCE_RESULT ,0x0127) -IPC_EVENT_TYPE1(DB_IPCE_APP_DOMAIN_NAME_RESULT ,0x0128) IPC_EVENT_TYPE1(DB_IPCE_FUNC_EVAL_ABORT_RESULT ,0x0129) IPC_EVENT_TYPE1(DB_IPCE_NAME_CHANGE ,0x012a) IPC_EVENT_TYPE1(DB_IPCE_UPDATE_MODULE_SYMS ,0x012c) @@ -66,10 +64,6 @@ IPC_EVENT_TYPE1(DB_IPCE_ENC_UPDATE_FUNCTION ,0x0137) IPC_EVENT_TYPE1(DB_IPCE_SET_METHOD_JMC_STATUS_RESULT ,0x013a) IPC_EVENT_TYPE1(DB_IPCE_GET_METHOD_JMC_STATUS_RESULT ,0x013b) IPC_EVENT_TYPE1(DB_IPCE_SET_MODULE_JMC_STATUS_RESULT ,0x013c) -IPC_EVENT_TYPE1(DB_IPCE_GET_THREAD_FOR_TASKID_RESULT ,0x013d) -IPC_EVENT_TYPE1(DB_IPCE_CREATE_CONNECTION ,0x0141) -IPC_EVENT_TYPE1(DB_IPCE_DESTROY_CONNECTION ,0x0142) -IPC_EVENT_TYPE1(DB_IPCE_CHANGE_CONNECTION ,0x0143) IPC_EVENT_TYPE1(DB_IPCE_FUNC_EVAL_RUDE_ABORT_RESULT ,0x0144) IPC_EVENT_TYPE1(DB_IPCE_EXCEPTION_CALLBACK2 ,0x0147) IPC_EVENT_TYPE1(DB_IPCE_EXCEPTION_UNWIND ,0x0148) @@ -79,9 +73,6 @@ IPC_EVENT_TYPE1(DB_IPCE_INTERCEPT_EXCEPTION_COMPLETE ,0x014B) IPC_EVENT_TYPE1(DB_IPCE_ENC_REMAP_COMPLETE ,0x014C) IPC_EVENT_TYPE1(DB_IPCE_CREATE_PROCESS ,0x014D) IPC_EVENT_TYPE1(DB_IPCE_ENC_ADD_FUNCTION ,0x014E) -IPC_EVENT_TYPE1(DB_IPCE_GET_NGEN_COMPILER_FLAGS_RESULT,0x0151) -IPC_EVENT_TYPE1(DB_IPCE_SET_NGEN_COMPILER_FLAGS_RESULT,0x0152) -IPC_EVENT_TYPE1(DB_IPCE_GET_GCHANDLE_INFO_RESULT ,0x0157) IPC_EVENT_TYPE1(DB_IPCE_LEFTSIDE_STARTUP ,0x015C) IPC_EVENT_TYPE1(DB_IPCE_METADATA_UPDATE ,0x015D) IPC_EVENT_TYPE1(DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT,0x015E) @@ -115,11 +106,8 @@ IPC_EVENT_TYPE2(DB_IPCE_SET_CLASS_LOAD_FLAG ,0x0217) IPC_EVENT_TYPE2(DB_IPCE_CONTINUE_EXCEPTION ,0x0219) IPC_EVENT_TYPE2(DB_IPCE_ATTACHING ,0x021A) IPC_EVENT_TYPE2(DB_IPCE_APPLY_CHANGES ,0x021B) -IPC_EVENT_TYPE2(DB_IPCE_SET_NGEN_COMPILER_FLAGS ,0x021F) -IPC_EVENT_TYPE2(DB_IPCE_GET_NGEN_COMPILER_FLAGS ,0x0220) IPC_EVENT_TYPE2(DB_IPCE_IS_TRANSITION_STUB ,0x0221) IPC_EVENT_TYPE2(DB_IPCE_IS_TRANSITION_STUB_RESULT ,0x0222) -IPC_EVENT_TYPE2(DB_IPCE_MODIFY_LOGSWITCH ,0x0223) IPC_EVENT_TYPE2(DB_IPCE_ENABLE_LOG_MESSAGES ,0x0224) IPC_EVENT_TYPE2(DB_IPCE_FUNC_EVAL ,0x0225) IPC_EVENT_TYPE2(DB_IPCE_SET_REFERENCE ,0x0228) @@ -132,13 +120,11 @@ IPC_EVENT_TYPE2(DB_IPCE_SET_VALUE_CLASS ,0x0234) IPC_EVENT_TYPE2(DB_IPCE_SET_METHOD_JMC_STATUS ,0x023a) IPC_EVENT_TYPE2(DB_IPCE_GET_METHOD_JMC_STATUS ,0x023b) IPC_EVENT_TYPE2(DB_IPCE_SET_MODULE_JMC_STATUS ,0x023c) -IPC_EVENT_TYPE2(DB_IPCE_GET_THREAD_FOR_TASKID ,0x023d) IPC_EVENT_TYPE2(DB_IPCE_FUNC_EVAL_RUDE_ABORT ,0x0241) IPC_EVENT_TYPE2(DB_IPCE_CREATE_HANDLE ,0x0244) IPC_EVENT_TYPE2(DB_IPCE_DISPOSE_HANDLE ,0x0245) IPC_EVENT_TYPE2(DB_IPCE_INTERCEPT_EXCEPTION ,0x0246) IPC_EVENT_TYPE2(DB_IPCE_DEBUGGER_INVALID ,0x0249) // An invalid event type -IPC_EVENT_TYPE2(DB_IPCE_GET_GCHANDLE_INFO ,0x0251) IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_1 ,0x0256) IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_2 ,0x0257) IPC_EVENT_TYPE2(DB_IPCE_DISABLE_OPTS ,0x0258) diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp index ceb5af5a059a2f..6f8083f0690f92 100644 --- a/src/coreclr/debug/shared/dbgtransportsession.cpp +++ b/src/coreclr/debug/shared/dbgtransportsession.cpp @@ -2114,7 +2114,7 @@ void DbgTransportSession::TransportWorker() // significant data to vary wildy from event to event). DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) { - DWORD cbBaseSize = offsetof(DebuggerIPCEvent, LeftSideStartupData); + DWORD cbBaseSize = offsetof(DebuggerIPCEvent, MetadataUpdateData); DWORD cbAdditionalSize = 0; switch (pEvent->type & DB_IPCE_TYPE_MASK) @@ -2133,12 +2133,10 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) case DB_IPCE_INTERCEPT_EXCEPTION_RESULT: case DB_IPCE_INTERCEPT_EXCEPTION_COMPLETE: case DB_IPCE_CREATE_PROCESS: - case DB_IPCE_SET_NGEN_COMPILER_FLAGS_RESULT: case DB_IPCE_LEFTSIDE_STARTUP: case DB_IPCE_ASYNC_BREAK: case DB_IPCE_CONTINUE: case DB_IPCE_ATTACHING: - case DB_IPCE_GET_NGEN_COMPILER_FLAGS: case DB_IPCE_DETACH_FROM_PROCESS: case DB_IPCE_CONTROL_C_EVENT_RESULT: case DB_IPCE_BEFORE_GARBAGE_COLLECTION: @@ -2211,10 +2209,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->FirstLogMessage); break; - case DB_IPCE_LOGSWITCH_SET_MESSAGE: - cbAdditionalSize = sizeof(pEvent->LogSwitchSettingMessage); - break; - case DB_IPCE_CREATE_APP_DOMAIN: cbAdditionalSize = sizeof(pEvent->AppDomainData); break; @@ -2267,22 +2261,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->SetJMCFunctionStatus); break; - case DB_IPCE_GET_THREAD_FOR_TASKID_RESULT: - cbAdditionalSize = sizeof(pEvent->GetThreadForTaskIdResult); - break; - - case DB_IPCE_CREATE_CONNECTION: - cbAdditionalSize = sizeof(pEvent->CreateConnection); - break; - - case DB_IPCE_DESTROY_CONNECTION: - cbAdditionalSize = sizeof(pEvent->ConnectionChange); - break; - - case DB_IPCE_CHANGE_CONNECTION: - cbAdditionalSize = sizeof(pEvent->ConnectionChange); - break; - case DB_IPCE_EXCEPTION_CALLBACK2: cbAdditionalSize = sizeof(pEvent->ExceptionCallback2); break; @@ -2303,14 +2281,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->EnCUpdate); break; - case DB_IPCE_GET_NGEN_COMPILER_FLAGS_RESULT: - cbAdditionalSize = sizeof(pEvent->JitDebugInfo); - break; - - case DB_IPCE_GET_GCHANDLE_INFO_RESULT: - cbAdditionalSize = sizeof(pEvent->GetGCHandleInfoResult); - break; - case DB_IPCE_SET_IP: cbAdditionalSize = sizeof(pEvent->SetIP); break; @@ -2353,10 +2323,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->ApplyChanges); break; - case DB_IPCE_SET_NGEN_COMPILER_FLAGS: - cbAdditionalSize = sizeof(pEvent->JitDebugInfo); - break; - case DB_IPCE_IS_TRANSITION_STUB: cbAdditionalSize = sizeof(pEvent->IsTransitionStub); break; @@ -2365,10 +2331,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->IsTransitionStubResult); break; - case DB_IPCE_MODIFY_LOGSWITCH: - cbAdditionalSize = sizeof(pEvent->LogSwitchSettingMessage); - break; - case DB_IPCE_ENABLE_LOG_MESSAGES: cbAdditionalSize = sizeof(pEvent->LogSwitchSettingMessage); break; @@ -2409,10 +2371,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->SetJMCFunctionStatus); break; - case DB_IPCE_GET_THREAD_FOR_TASKID: - cbAdditionalSize = sizeof(pEvent->GetThreadForTaskId); - break; - case DB_IPCE_FUNC_EVAL_RUDE_ABORT: cbAdditionalSize = sizeof(pEvent->FuncEvalRudeAbort); break; @@ -2429,10 +2387,6 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) cbAdditionalSize = sizeof(pEvent->InterceptException); break; - case DB_IPCE_GET_GCHANDLE_INFO: - cbAdditionalSize = sizeof(pEvent->GetGCHandleInfo); - break; - case DB_IPCE_CUSTOM_NOTIFICATION: cbAdditionalSize = sizeof(pEvent->CustomNotification); break; diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h index 90bf54abfee821..ba796e2df778e1 100644 --- a/src/coreclr/vm/dbginterface.h +++ b/src/coreclr/vm/dbginterface.h @@ -249,11 +249,6 @@ class DebugInterface virtual bool IsJMCMethod(Module* pModule, mdMethodDef tkMethod) = 0; - virtual void SendLogSwitchSetting (int iLevel, - int iReason, - _In_z_ LPCWSTR pLogSwitchName, - _In_z_ LPCWSTR pParentSwitchName) = 0; - virtual bool IsLoggingEnabled (void) = 0; virtual bool GetILOffsetFromNative (MethodDesc *PFD, @@ -348,11 +343,6 @@ class DebugInterface // Used by the interpreter to avoid calling OnMethodEnter when not stepping. virtual bool IsMethodEnterEnabled() = 0; - // notification for SQL fiber debugging support - virtual void CreateConnection(CONNID dwConnectionId, _In_z_ WCHAR *wzName) = 0; - virtual void DestroyConnection(CONNID dwConnectionId) = 0; - virtual void ChangeConnection(CONNID dwConnectionId) = 0; - // // This function is used to identify the helper thread. // diff --git a/src/coreclr/vm/eedbginterface.h b/src/coreclr/vm/eedbginterface.h index a6fd0182fd5a19..f972e89e645488 100644 --- a/src/coreclr/vm/eedbginterface.h +++ b/src/coreclr/vm/eedbginterface.h @@ -316,9 +316,6 @@ class EEDebugInterface #ifndef DACCESS_COMPILE - virtual void DebuggerModifyingLogSwitch (int iNewLevel, - const WCHAR *pLogSwitchName) = 0; - virtual HRESULT SetIPFromSrcToDst(Thread *pThread, SLOT addrStart, DWORD offFrom, diff --git a/src/coreclr/vm/eedbginterfaceimpl.cpp b/src/coreclr/vm/eedbginterfaceimpl.cpp index 2c33b9c94a7fc7..031659f824ac4a 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/vm/eedbginterfaceimpl.cpp @@ -1317,17 +1317,6 @@ void EEDbgInterfaceImpl::GetRuntimeOffsets(SIZE_T *pTLSIndex, *pEEIsManagedExceptionStateMask = Thread::TSNC_DebuggerIsManagedException; } -void EEDbgInterfaceImpl::DebuggerModifyingLogSwitch (int iNewLevel, - const WCHAR *pLogSwitchName) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; -} - HRESULT EEDbgInterfaceImpl::SetIPFromSrcToDst(Thread *pThread, SLOT addrStart, diff --git a/src/coreclr/vm/eedbginterfaceimpl.h b/src/coreclr/vm/eedbginterfaceimpl.h index 3e59d15da56ab3..acc1b2692b8d1f 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.h +++ b/src/coreclr/vm/eedbginterfaceimpl.h @@ -278,9 +278,6 @@ class EEDbgInterfaceImpl : public EEDebugInterface SIZE_T *pEEFrameNextOffset, DWORD *pEEIsManagedExceptionStateMask); - void DebuggerModifyingLogSwitch (int iNewLevel, - const WCHAR *pLogSwitchName); - HRESULT SetIPFromSrcToDst(Thread *pThread, SLOT addrStart, DWORD offFrom, From f0542c1ace3f66ff93a6e8f666443fe0b3329944 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 May 2026 21:10:44 -0700 Subject: [PATCH 2/5] fix build breaks and address copilot feedback --- src/coreclr/debug/di/module.cpp | 4 +- src/coreclr/debug/di/process.cpp | 98 +++++++--------------------- src/coreclr/debug/di/rspriv.h | 4 -- src/coreclr/debug/di/valuehome.cpp | 4 +- src/coreclr/debug/ee/debugger.cpp | 34 +++------- src/coreclr/debug/ee/debugger.h | 2 +- src/coreclr/debug/ee/funceval.cpp | 56 ++++++++-------- src/coreclr/debug/inc/dbgipcevents.h | 9 ++- src/coreclr/inc/dbgportable.h | 11 ++++ 9 files changed, 79 insertions(+), 143 deletions(-) diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 50b78b0bb1273e..558fccbb0a34f7 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -548,7 +548,7 @@ void CordbModule::RefreshMetaData() // // Update it on the RS // - bufferMetaData.Init(PTR_TO_CORDB_ADDRESS(event.MetadataUpdateRequest.pMetadataStart), (ULONG) event.MetadataUpdateRequest.nMetadataSize); + bufferMetaData.Init(event.MetadataUpdateRequest.pMetadataStart, (ULONG) event.MetadataUpdateRequest.nMetadataSize); // init the cleanup object to ensure the buffer gets destroyed later cleanup.bufferMetaData = bufferMetaData; @@ -2217,7 +2217,7 @@ HRESULT CordbModule::ApplyChangesInternal(ULONG cbMetaData, retEvent->type == DB_IPCE_ENC_ADD_FUNCTION) { // Update the function collection to reflect this edit - hr = pModule->UpdateFunction(retEvent->EnCUpdate.memberMetadataToken, retEvent->EnCUpdate.newVersionNumber, NULL); + hr = pModule->UpdateFunction(retEvent->EnCUpdate.memberMetadataToken, (SIZE_T)(ULONG64)retEvent->EnCUpdate.newVersionNumber, NULL); } // mark the class and relevant type as old so we update it next time we try to query it diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index f1ea0be2af89a0..828abcd75fc578 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -5170,13 +5170,26 @@ void CordbProcess::RawDispatchEvent( _ASSERTE(pThread != NULL); _ASSERTE(pAppDomain != NULL); - // szCategory and szContent are CORDB_ADDRESS pointers into the target. - // Read the null-terminated strings via ReadVirtual. The NewArrayHolders - // ensure cleanup when this block exits. - NewArrayHolder wszCategory( - ReadTargetNullTerminatedString(pEvent->FirstLogMessage.szCategory)); - NewArrayHolder wszContent( - ReadTargetNullTerminatedString(pEvent->FirstLogMessage.szContent)); + // Read category and content strings from target memory using + // the address and character count provided in the event. + ULONG cchCategory = pEvent->FirstLogMessage.cchCategory; + NewArrayHolder wszCategory(new WCHAR[cchCategory + 1]); + ULONG32 cbRead; + IfFailThrow(m_pDACDataTarget->ReadVirtual( + pEvent->FirstLogMessage.szCategory, + reinterpret_cast((WCHAR *)wszCategory), + cchCategory * sizeof(WCHAR), + &cbRead)); + wszCategory[cchCategory] = W('\0'); + + ULONG cchContent = pEvent->FirstLogMessage.cchContent; + NewArrayHolder wszContent(new WCHAR[cchContent + 1]); + IfFailThrow(m_pDACDataTarget->ReadVirtual( + pEvent->FirstLogMessage.szContent, + reinterpret_cast((WCHAR *)wszContent), + cchContent * sizeof(WCHAR), + &cbRead)); + wszContent[cchContent] = W('\0'); { PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); @@ -5448,12 +5461,12 @@ void CordbProcess::RawDispatchEvent( // lookup the version of the function that we are mapping from // this is the one that is currently running pCurFunction = pModule->LookupOrCreateFunction( - pEvent->EnCRemap.funcMetadataToken, pEvent->EnCRemap.currentVersionNumber); + pEvent->EnCRemap.funcMetadataToken, (SIZE_T)(ULONG64)pEvent->EnCRemap.currentVersionNumber); // lookup the version of the function that we are mapping to // it will always be the most recent pResumeFunction = pModule->LookupOrCreateFunction( - pEvent->EnCRemap.funcMetadataToken, pEvent->EnCRemap.resumeVersionNumber); + pEvent->EnCRemap.funcMetadataToken, (SIZE_T)(ULONG64)pEvent->EnCRemap.resumeVersionNumber); _ASSERTE(pCurFunction->GetEnCVersionNumber() < pResumeFunction->GetEnCVersionNumber()); @@ -9188,73 +9201,6 @@ void Ls_Rs_StringBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget) } } -//--------------------------------------------------------------------------------------- -// Read a null-terminated WCHAR string from the target process. -// The caller owns the returned buffer and should free it with delete[] (or wrap -// it in a NewArrayHolder for automatic cleanup). -// -// Arguments: -// targetAddr - CORDB_ADDRESS of the null-terminated WCHAR string in the target. -// -// Returns: -// A heap-allocated WCHAR* copy of the string, or NULL if targetAddr is 0. -// -// Throws on ReadVirtual failure. -//--------------------------------------------------------------------------------------- -WCHAR * CordbProcess::ReadTargetNullTerminatedString(CORDB_ADDRESS targetAddr) -{ - if (targetAddr == 0) - { - return NULL; - } - - // Read the string in chunks to find the null terminator, similar to DacInstantiateStringW. - const ULONG32 chunkSize = 256; - const ULONG32 maxChars = 512 * 1024; // 1 MB cap to prevent unbounded allocation from corrupt targets - NewArrayHolder buffer(NULL); - ULONG32 totalChars = 0; - - for (;;) - { - if (totalChars >= maxChars) - { - ThrowHR(CORDBG_E_TARGET_INCONSISTENT); - } - - ULONG32 newSize = totalChars + chunkSize; - WCHAR * newBuffer = new WCHAR[newSize]; - if (buffer != NULL) - { - memcpy(newBuffer, (WCHAR *)buffer, totalChars * sizeof(WCHAR)); - } - buffer = newBuffer; - - ULONG32 cbRead; - HRESULT hr = m_pDACDataTarget->ReadVirtual( - targetAddr + totalChars * sizeof(WCHAR), - reinterpret_cast(buffer.GetValue() + totalChars), - chunkSize * sizeof(WCHAR), - &cbRead); - IfFailThrow(hr); - - ULONG32 charsRead = cbRead / sizeof(WCHAR); - for (ULONG32 i = 0; i < charsRead; i++) - { - if (buffer[totalChars + i] == W('\0')) - { - buffer.SuppressRelease(); - return (WCHAR *)buffer; - } - } - totalChars += charsRead; - - if (charsRead < chunkSize) - { - ThrowHR(CORDBG_E_TARGET_INCONSISTENT); - } - } -} - //--------------------------------------------------------------------------------------- // Copy a managed debug event from the target process into this local process // diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 316e237f52adef..d376dea2ba6ebc 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -3222,10 +3222,6 @@ class CordbProcess : // Queue the RC event. void QueueRCEvent(DebuggerIPCEvent * pManagedEvent); - // Read a null-terminated WCHAR string from the target process. - // Caller owns the returned buffer (use NewArrayHolder for RAII cleanup). - _Ret_maybenull_ WCHAR * ReadTargetNullTerminatedString(CORDB_ADDRESS targetAddr); - // This copies a managed debug event from the IPC block and to pManagedEvent. // The event still needs to be marshalled. void CopyRCEventFromIPCBlock(DebuggerIPCEvent * pManagedEvent); diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index ff110cf88875bf..c9014871af9944 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -440,7 +440,7 @@ void MemRegValueHome::GetEnregisteredValue(MemoryRange valueOutBuffer) void FloatRegValueHome::CopyToIPCEType(RemoteAddress * pRegAddr) { pRegAddr->kind = RAK_FLOAT; - pRegAddr->reg1Addr = NULL; + pRegAddr->reg1Addr = (CORDB_ADDRESS)0; pRegAddr->floatIndex = m_floatIndex; } // FloatRegValueHome::CopyToIPCEType @@ -915,7 +915,7 @@ void HandleValueHome::SetValue(MemoryRange src, CordbType * pType) m_pProcess->InitIPCEvent(&event, DB_IPCE_SET_REFERENCE, true, VMPTR_AppDomain::NullPtr()); - event.SetReference.objectRefAddress = NULL; + event.SetReference.objectRefAddress = (CORDB_ADDRESS)0; event.SetReference.vmObjectHandle = m_vmObjectHandle; event.SetReference.newReference = PTR_TO_CORDB_ADDRESS(*((void **)src.StartAddress())); diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 8f66e4290530fa..e49101dade8b49 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -11019,7 +11019,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) DebuggerIPCEvent * pResult = m_pRCThread->GetIPCEventReceiveBuffer(); InitIPCEvent(pResult, DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT, NULL); - pResult->MetadataUpdateRequest.pMetadataStart = (CORDB_ADDRESS)pData; + pResult->MetadataUpdateRequest.pMetadataStart = PTR_TO_CORDB_ADDRESS(pData); pResult->MetadataUpdateRequest.nMetadataSize = countBytes; pResult->hr = hr; LOG((LF_CORDB, LL_INFO1000000, "D::HIPCE metadataStart=0x%x, nMetadataSize=0x%x\n", pData, countBytes)); @@ -13405,9 +13405,9 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, // Signal the RS to tell us what to do SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started.\n", tid)); SignalHijackStarted(); - SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started complete. DebugCounter=0x%x\n", tid, (UINT)const_cast&>(pFcd->debugCounter))); + SPEW(fprintf(stderr, "0x%x D::FCHF: Signaling hijack started complete. DebugCounter=0x%x\n", tid, (UINT)pFcd->debugCounter)); - if ((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_WAIT) + if ((HijackAction)pFcd->action == HIJACK_ACTION_WAIT) { // This exception does NOT belong to the CLR. // If we belong to the CLR, then we either: @@ -13456,10 +13456,10 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, SPEW(fprintf(stderr, "0x%x D::FCHF: signaling HijackComplete.\n", tid)); SignalHijackComplete(); - SPEW(fprintf(stderr, "0x%x D::FCHF: done signaling HijackComplete. DebugCounter=0x%x\n", tid, (UINT)const_cast&>(pFcd->debugCounter))); + SPEW(fprintf(stderr, "0x%x D::FCHF: done signaling HijackComplete. DebugCounter=0x%x\n", tid, (UINT)pFcd->debugCounter)); // we should know what we are about to do now - _ASSERTE((HijackAction)const_cast&>(pFcd->action) != HIJACK_ACTION_WAIT); + _ASSERTE((HijackAction)pFcd->action != HIJACK_ACTION_WAIT); // cleanup from above SPEW(fprintf(stderr, "0x%x D::FCHF: set debugger word = NULL.\n", tid)); @@ -13467,7 +13467,7 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, } // end can't stop region - if ((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_EXIT_HANDLED) + if ((HijackAction)pFcd->action == HIJACK_ACTION_EXIT_HANDLED) { SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_EXECUTION\n", tid)); #if defined(OUT_OF_PROCESS_SETTHREADCONTEXT) && !defined(DACCESS_COMPILE) @@ -13481,7 +13481,7 @@ LONG Debugger::FirstChanceSuspendHijackWorker(CONTEXT *pContext, else { SPEW(fprintf(stderr, "0x%x D::FCHF: exiting with CONTINUE_SEARCH\n", tid)); - _ASSERTE((HijackAction)const_cast&>(pFcd->action) == HIJACK_ACTION_EXIT_UNHANDLED); + _ASSERTE((HijackAction)pFcd->action == HIJACK_ACTION_EXIT_UNHANDLED); return EXCEPTION_CONTINUE_SEARCH; } } @@ -13862,24 +13862,6 @@ Debugger::InsertToMethodInfoList( DebuggerMethodInfo *dmi ) return hr; } -//----------------------------------------------------------------------------- -// Helper to get an SString through the IPC buffer. -// We do this by putting the SString data into a LS_RS_buffer object, -// and then the RS reads it out as soon as it's queued. -// It's very very important that the SString's buffer is around while we send the event. -// So we pass the SString by reference in case there's an implicit conversion (because -// we don't want to do the conversion on a temporary object and then lose that object). -//----------------------------------------------------------------------------- -void SetLSBufferFromSString(Ls_Rs_StringBuffer * pBuffer, SString & str) -{ - // Copy string contents (+1 for null terminator) into a LS_RS_Buffer. - // Then the RS can pull it out as a null-terminated string. - pBuffer->SetLsData( - (BYTE*) str.GetUnicode(), - (str.GetCount() +1)* sizeof(WCHAR) - ); -} - //************************************************************* // This method sends a log message over to the right side for the debugger to log it. // @@ -13966,7 +13948,9 @@ void Debugger::SendRawLogMessage( ipce->FirstLogMessage.iLevel = iLevel; ipce->FirstLogMessage.szCategory = PTR_TO_CORDB_ADDRESS(pCategory->GetUnicode()); + ipce->FirstLogMessage.cchCategory = (ULONG)pCategory->GetCount(); ipce->FirstLogMessage.szContent = PTR_TO_CORDB_ADDRESS(pMessage->GetUnicode()); + ipce->FirstLogMessage.cchContent = (ULONG)pMessage->GetCount(); m_pRCThread->SendIPCEvent(); } diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 2a0543929969c6..08bb7ffe2815e9 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -3501,7 +3501,7 @@ class DebuggerEval if (argData[i].fullArgType != (CORDB_ADDRESS)0) { _ASSERTE(g_pDebugger != NULL); - g_pDebugger->ReleaseRemoteBuffer((BYTE*)(CORDB_ADDRESS)argData[i].fullArgType, true); + g_pDebugger->ReleaseRemoteBuffer((BYTE*)CORDB_ADDRESS_TO_PTR(argData[i].fullArgType), true); } } diff --git a/src/coreclr/debug/ee/funceval.cpp b/src/coreclr/debug/ee/funceval.cpp index 5a402cd640df2a..29c883f57f77db 100644 --- a/src/coreclr/debug/ee/funceval.cpp +++ b/src/coreclr/debug/ee/funceval.cpp @@ -874,7 +874,7 @@ static void GetFuncEvalArgValue(DebuggerEval *pDE, LPVOID pAddr = NULL; INT64 bigVal = 0; - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { pAddr = *((void **)pMaybeInteriorPtrArg); } @@ -907,7 +907,7 @@ static void GetFuncEvalArgValue(DebuggerEval *pDE, } else { - _ASSERTE(pFEAD->argAddr != NULL); + _ASSERTE(pFEAD->argAddr != (CORDB_ADDRESS)0); #if defined(ENREGISTERED_PARAMTYPE_MAXSIZE) if (ArgIterator::IsArgPassedByRef(argTH)) { @@ -946,7 +946,7 @@ static void GetFuncEvalArgValue(DebuggerEval *pDE, } else { - if (pFEAD->argAddr) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { *pArgument = PtrToArgSlot(pAddr); } @@ -996,7 +996,7 @@ static void GetFuncEvalArgValue(DebuggerEval *pDE, pSource = pBufferArg; } - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { if (!isByRef) { @@ -1262,7 +1262,7 @@ static void SetFuncEvalByRefArgValue(DebuggerEval *pDE, // If this was a literal arg, then copy the updated primitive back into the literal. memcpy(pFEAD->argLiteralData, &source, sizeof(pFEAD->argLiteralData)); } - else if (pFEAD->argAddr != NULL) + else if (pFEAD->argAddr != (CORDB_ADDRESS)0) { *((INT64 *)byRefMaybeInteriorPtrArg) = source; return; @@ -1344,7 +1344,7 @@ static void SetFuncEvalByRefArgValue(DebuggerEval *pDE, memcpy(pFEAD->argLiteralData, &source, sizeof(source)); } } - else if (pFEAD->argAddr == NULL) + else if (pFEAD->argAddr == (CORDB_ADDRESS)0) { // If the 32bit value is enregistered, copy it back to the proper regs. @@ -1442,7 +1442,7 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, // In case any of the arguments is a by ref argument and points into the GC heap, // we need to GC protect their addresses as well. - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { pByRefMaybeInteriorPtrArray[currArgIndex] = CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); } @@ -1460,9 +1460,9 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, // _ASSERTE(sizeof(void *) == sizeof(INT64)); - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { - pMaybeInteriorPtrArray[currArgIndex] = *((void **)(pFEAD->argAddr)); + pMaybeInteriorPtrArray[currArgIndex] = *((void **)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr)); #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) { @@ -1510,9 +1510,9 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, // // If the value type address could be an interior pointer. // - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { - pMaybeInteriorPtrArray[currArgIndex] = ((void **)(pFEAD->argAddr)); + pMaybeInteriorPtrArray[currArgIndex] = ((void **)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr)); } INDEBUG(pDataLocationArray[currArgIndex] |= DL_MaybeInteriorPtrArray); @@ -1524,18 +1524,18 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, case ELEMENT_TYPE_ARRAY: case ELEMENT_TYPE_SZARRAY: - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { if (pFEAD->argIsHandleValue) { - OBJECTHANDLE oh = (OBJECTHANDLE)(pFEAD->argAddr); + OBJECTHANDLE oh = (OBJECTHANDLE)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); pBufferForArgsArray[currArgIndex] = (INT64)(size_t)oh; INDEBUG(pDataLocationArray[currArgIndex] |= DL_BufferForArgsArray); } else { - pObjectRefArray[currArgIndex] = *((OBJECTREF *)(pFEAD->argAddr)); + pObjectRefArray[currArgIndex] = *((OBJECTREF *)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr)); INDEBUG(pDataLocationArray[currArgIndex] |= DL_ObjectRefArray); } @@ -1580,7 +1580,7 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, #ifdef TARGET_X86 _ASSERTE(sizeof(void *) == sizeof(INT32)); - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { if (pFEAD->argIsHandleValue) { @@ -1590,7 +1590,7 @@ static void GCProtectAllPassedArgs(DebuggerEval *pDE, } else { - pMaybeInteriorPtrArray[currArgIndex] = *((void **)(pFEAD->argAddr)); + pMaybeInteriorPtrArray[currArgIndex] = *((void **)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr)); #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) { @@ -1792,7 +1792,7 @@ void BoxFuncEvalThisParameter(DebuggerEval *pDE, { GCX_FORBID(); //pAddr is unprotected from the time we initialize it - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { _ASSERTE(pDataLocationArray[0] & DL_MaybeInteriorPtrArray); pAddr = pMaybeInteriorPtrArray[0]; @@ -2019,7 +2019,7 @@ void BoxFuncEvalArguments(DebuggerEval *pDE, INT64 bigVal; LPVOID pAddr = NULL; - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { _ASSERTE(pDataLocationArray[currArgIndex] & DL_MaybeInteriorPtrArray); pAddr = pMaybeInteriorPtrArray[currArgIndex]; @@ -2124,7 +2124,7 @@ void GatherFuncEvalMethodInfo(DebuggerEval *pDE, // We should have a valid this pointer. // @todo: But the check should cover the register kind as well! // - if ((argData[0].argHome.kind == RAK_NONE) && (argData[0].argAddr == NULL)) + if ((argData[0].argHome.kind == RAK_NONE) && (argData[0].argAddr == (CORDB_ADDRESS)0)) { COMPlusThrow(kArgumentNullException); } @@ -2330,9 +2330,9 @@ void CopyArgsToBuffer(DebuggerEval *pDE, case ELEMENT_TYPE_U8: case ELEMENT_TYPE_R8: - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { - *pDest = *(INT64*)(pFEAD->argAddr); + *pDest = *(INT64*)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) { @@ -2405,18 +2405,18 @@ void CopyArgsToBuffer(DebuggerEval *pDE, case ELEMENT_TYPE_ARRAY: case ELEMENT_TYPE_SZARRAY: - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { if (!isByRef) { if (pFEAD->argIsHandleValue) { - OBJECTHANDLE oh = (OBJECTHANDLE)(pFEAD->argAddr); + OBJECTHANDLE oh = (OBJECTHANDLE)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); *pDest = (INT64)(size_t)oh; } else { - *pDest = *((SIZE_T*)(pFEAD->argAddr)); + *pDest = *((SIZE_T*)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr)); } #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) @@ -2429,11 +2429,11 @@ void CopyArgsToBuffer(DebuggerEval *pDE, { if (pFEAD->argIsHandleValue) { - *pDest = (INT64)(size_t)(pFEAD->argAddr); + *pDest = (INT64)(size_t)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); } else { - *pDest = *(SIZE_T*)(pFEAD->argAddr); + *pDest = *(SIZE_T*)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); } #ifdef _DEBUG if (currArgIndex < MAX_DATA_LOCATIONS_TRACKED) @@ -2497,13 +2497,13 @@ void CopyArgsToBuffer(DebuggerEval *pDE, default: // 4-byte, 2-byte, or 1-byte values - if (pFEAD->argAddr != NULL) + if (pFEAD->argAddr != (CORDB_ADDRESS)0) { if (!isByRef) { if (pFEAD->argIsHandleValue) { - OBJECTHANDLE oh = (OBJECTHANDLE)(pFEAD->argAddr); + OBJECTHANDLE oh = (OBJECTHANDLE)CORDB_ADDRESS_TO_PTR(pFEAD->argAddr); *pDest = (INT64)(size_t)oh; } else diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 7c973afd5d0ccc..a9a9bceaaa01d7 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1644,7 +1644,7 @@ enum NameChangeType struct MSLAYOUT DebuggerIPCE_FuncEvalArgData { RemoteAddress argHome; // enregistered variable home - CORDB_ADDRESS argAddr; // address if not enregistered + Portable argAddr; // address if not enregistered Portable argElementType; Portable fullArgTypeNodeCount; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) Portable fullArgType; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types) @@ -2079,10 +2079,12 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - int iLevel; + Portable iLevel; Portable szCategory; + Portable cchCategory; Portable szContent; + Portable cchContent; } FirstLogMessage; struct MSLAYOUT @@ -2265,7 +2267,4 @@ struct MSLAYOUT DebuggerIPCEvent static_assert(sizeof(DebuggerIPCEvent) <= CorDBIPC_BUFFER_SIZE); static_assert(CorDBIPC_TRANSPORT_BUFFER_SIZE <= CorDBIPC_BUFFER_SIZE); -// 2*sizeof(WCHAR) for the two string terminating characters in the FirstLogMessage -#define LOG_MSG_PADDING 4 - #endif /* _DbgIPCEvents_h_ */ diff --git a/src/coreclr/inc/dbgportable.h b/src/coreclr/inc/dbgportable.h index b9306ca9b0ca77..92644ec637115d 100644 --- a/src/coreclr/inc/dbgportable.h +++ b/src/coreclr/inc/dbgportable.h @@ -91,6 +91,17 @@ class Portable #endif // DBG_BYTE_SWAP_REQUIRED } + // Volatile-qualified accessor for fields accessed through volatile pointers + operator T () const volatile + { + T data = m_data; +#ifdef DBG_BYTE_SWAP_REQUIRED + return ByteSwap(data); +#else // DBG_BYTE_SWAP_REQUIRED + return data; +#endif // DBG_BYTE_SWAP_REQUIRED + } + bool operator == (T other) const { #ifdef DBG_BYTE_SWAP_REQUIRED From bbdae946df1a941bf51580d4b86d6d509bb9e16c Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 May 2026 21:32:25 -0700 Subject: [PATCH 3/5] more build fixes --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 2 +- src/coreclr/debug/di/rsthread.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 2785108723ebba..8fb121f35546fc 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -1823,7 +1823,7 @@ TypeHandle DacDbiInterfaceImpl::TypeDataWalk::ReadLoadedTypeArg(TypeHandleReadTy switch (elementType) { case ELEMENT_TYPE_PTR: - _ASSERTE(pData->numTypeArgs == 1); + _ASSERTE(pData->numTypeArgs == (UINT)1); return PtrOrByRefTypeArg(pData, retrieveWhich); break; diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 9e9eef25c2f2b0..b4d86c68ebf221 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -80,7 +80,7 @@ CordbThread::CordbThread(CordbProcess * pProcess, VMPTR_Thread vmThread) : m_fFloatStateValid(false), m_floatStackTop(0), m_fException(false), - m_EnCRemapFunctionIP(NULL), + m_EnCRemapFunctionIP(0), m_userState(kInvalidUserState), m_hCachedThread(INVALID_HANDLE_VALUE), m_hCachedOutOfProcThread(INVALID_HANDLE_VALUE) @@ -1340,7 +1340,7 @@ void CordbThread::MarkStackFramesDirty() // Clear the stashed EnC remap IP address if any // This is important to ensure we don't try to write into LS memory which is no longer // being used to hold the remap IP. - m_EnCRemapFunctionIP = NULL; + m_EnCRemapFunctionIP = 0; m_fContextFresh = false; // invalidate the cached active CONTEXT m_vmLeftSideContext = VMPTR_CONTEXT::NullPtr(); // set the LS pointer to the active CONTEXT to NULL @@ -2514,7 +2514,7 @@ HRESULT CordbThread::SetRemapIP(SIZE_T offset) // Prevent SetRemapIP from being called twice for the same RemapOpportunity // If we don't get any calls to RemapFunction, this member will be cleared in // code:CordbThread::MarkStackFramesDirty when Continue is called - m_EnCRemapFunctionIP = NULL; + m_EnCRemapFunctionIP = 0; return hr; } @@ -9279,7 +9279,7 @@ HRESULT CordbEval::GatherArgInfo(ICorDebugValue *pValue, argData->argIsHandleValue = false; argData->argIsLiteral = false; - argData->fullArgType = NULL; + argData->fullArgType = (CORDB_ADDRESS)0; argData->fullArgTypeNodeCount = 0; // We have to have knowledge of our value implementation here, From 120c425b21d5ef37ae06187fb582b7ec4828c953 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 May 2026 21:58:49 -0700 Subject: [PATCH 4/5] more build fixes --- src/coreclr/debug/di/process.cpp | 2 +- src/coreclr/debug/di/shimcallback.cpp | 11 +++++++---- src/coreclr/debug/ee/funceval.cpp | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 828abcd75fc578..acba841e2ed060 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -13022,7 +13022,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven fcd.debugCounter = 0; SafeReadStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd); - _ASSERTE(fcd.debugCounter == 1); + _ASSERTE(fcd.debugCounter == (UINT)1); DequeueUnmanagedEvent(pUnmanagedThread); } diff --git a/src/coreclr/debug/di/shimcallback.cpp b/src/coreclr/debug/di/shimcallback.cpp index f557686c015910..7a4370440a0109 100644 --- a/src/coreclr/debug/di/shimcallback.cpp +++ b/src/coreclr/debug/di/shimcallback.cpp @@ -1383,10 +1383,13 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT this->m_pProcess.Assign(pProcess); this->m_pThread.Assign(pThread); - this->m_contextSize = contextSize; - m_context = new (nothrow) BYTE[this->m_contextSize]; - if (m_context != NULL) - memcpy(m_context, pContext, this->m_contextSize); + this->m_contextSize = min(contextSize, (ULONG32)0x1000); + if (pContext != NULL && this->m_contextSize > 0) + { + m_context = new (nothrow) BYTE[this->m_contextSize]; + if (m_context != NULL) + memcpy(m_context, pContext, this->m_contextSize); + } } HRESULT Dispatch(DispatchArgs args) diff --git a/src/coreclr/debug/ee/funceval.cpp b/src/coreclr/debug/ee/funceval.cpp index 29c883f57f77db..263beaa911bbfc 100644 --- a/src/coreclr/debug/ee/funceval.cpp +++ b/src/coreclr/debug/ee/funceval.cpp @@ -1821,7 +1821,7 @@ void BoxFuncEvalThisParameter(DebuggerEval *pDE, // type yet). // // A buffer should have been allocated for the full struct type - _ASSERTE(argData[0].fullArgType != NULL); + _ASSERTE(argData[0].fullArgType != (CORDB_ADDRESS)0); Debugger::TypeDataWalk walk((DebuggerIPCE_TypeArgData *) CORDB_ADDRESS_TO_PTR(argData[0].fullArgType), argData[0].fullArgTypeNodeCount); TypeHandle typeHandle = walk.ReadTypeHandle(); From 69f4017a7214e5eb6fb7675647365d1757983d5d Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 7 May 2026 22:25:34 -0700 Subject: [PATCH 5/5] fix build breaks and address copilot feedback --- src/coreclr/debug/di/process.cpp | 17 +++++++++++++---- src/coreclr/debug/di/rsthread.cpp | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index acba841e2ed060..b779b5a990727c 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -5173,21 +5173,30 @@ void CordbProcess::RawDispatchEvent( // Read category and content strings from target memory using // the address and character count provided in the event. ULONG cchCategory = pEvent->FirstLogMessage.cchCategory; + ULONG cchContent = pEvent->FirstLogMessage.cchContent; + + const ULONG cchMax = 0x10000; + if (cchCategory > cchMax || cchContent > cchMax) + { + IfFailThrow(E_UNEXPECTED); + } + NewArrayHolder wszCategory(new WCHAR[cchCategory + 1]); ULONG32 cbRead; + ULONG32 cbExpected = cchCategory * sizeof(WCHAR); IfFailThrow(m_pDACDataTarget->ReadVirtual( pEvent->FirstLogMessage.szCategory, reinterpret_cast((WCHAR *)wszCategory), - cchCategory * sizeof(WCHAR), + cbExpected, &cbRead)); wszCategory[cchCategory] = W('\0'); - ULONG cchContent = pEvent->FirstLogMessage.cchContent; NewArrayHolder wszContent(new WCHAR[cchContent + 1]); + cbExpected = cchContent * sizeof(WCHAR); IfFailThrow(m_pDACDataTarget->ReadVirtual( pEvent->FirstLogMessage.szContent, reinterpret_cast((WCHAR *)wszContent), - cchContent * sizeof(WCHAR), + cbExpected, &cbRead)); wszContent[cchContent] = W('\0'); @@ -5479,7 +5488,7 @@ void CordbProcess::RawDispatchEvent( // We want to be absolutely sure we don't accidentally keep a stale pointer // around because it would point to arbitrary stack space in the CLR potentially // leading to stack corruption. - _ASSERTE( pThread->m_EnCRemapFunctionIP == NULL ); + _ASSERTE( pThread->m_EnCRemapFunctionIP == (CORDB_ADDRESS)0 ); // Stash the address of the remap IP buffer. This indicates that calling // RemapFunction is valid and provides a communications channel between the RS diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index b4d86c68ebf221..fe1bab685a1252 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -10160,6 +10160,8 @@ HRESULT CordbEval::NewStringWithLength(LPCWSTR wszString, UINT iLength) // Length of the string? Don't account for null as COMString::NewString is length-based + if (iLength > UINT_MAX / sizeof(WCHAR)) + return E_INVALIDARG; UINT cbString = (UINT)(iLength * sizeof(WCHAR)); // Remember that we're doing a func eval for a new string.