From 52868236dc763903ffc190727edb190289a6d784 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 11 May 2026 16:53:20 -0700 Subject: [PATCH 1/7] change vmptr portable --- src/coreclr/debug/ee/debugger.cpp | 4 +- src/coreclr/debug/inc/dbgipcevents.h | 102 +++++++++++++-------------- src/coreclr/inc/dbgportable.h | 37 ++++++++++ 3 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 561f7c73d5f61f..eb4dcc566fa392 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -11437,7 +11437,7 @@ void Debugger::TypeHandleToBasicTypeInfo(AppDomain *pAppDomain, TypeHandle th, D case ELEMENT_TYPE_BYREF: res->vmTypeHandle = WrapTypeHandle(th); res->metadataToken = mdTokenNil; - res->vmAssembly.SetRawPtr(NULL); + res->vmAssembly = VMPTR_Assembly::NullPtr(); break; case ELEMENT_TYPE_CLASS: @@ -11455,7 +11455,7 @@ void Debugger::TypeHandleToBasicTypeInfo(AppDomain *pAppDomain, TypeHandle th, D default: res->vmTypeHandle = VMPTR_TypeHandle::NullPtr(); res->metadataToken = mdTokenNil; - res->vmAssembly.SetRawPtr(NULL); + res->vmAssembly = VMPTR_Assembly::NullPtr(); break; } return; diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index a9a9bceaaa01d7..b69bb36687d1d4 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -396,7 +396,10 @@ class MSLAYOUT GeneralRsPointer inline ULONG_PTR LsPtrToCookie(GeneralLsPointer p) { return (ULONG_PTR)(CORDB_ADDRESS)p.m_ptr; } -#define VmPtrToCookie(vm) LsPtrToCookie((vm).ToLsPtr()) +template +inline ULONG_PTR VmPtrToCookie(T vm) { return LsPtrToCookie(vm.ToLsPtr()); } +template +inline ULONG_PTR VmPtrToCookie(Portable vm) { return LsPtrToCookie(static_cast(vm).ToLsPtr()); } #ifdef RIGHT_SIDE_COMPILE @@ -643,7 +646,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: - Portable m_addr; + CORDB_ADDRESS m_addr; public: typedef VMPTR_Base VMPTR_This; @@ -687,9 +690,11 @@ class MSLAYOUT VMPTR_Base // This will set initialize from a Target pointer. Since this is happening in the // Left-side (Target), the pointer is local. // This is commonly used by the Left-side to create a VMPTR_ for a notification event. - void SetRawPtr(TTargetPtr * ptr) + static VMPTR_This MakePtr(TTargetPtr * ptr) { - m_addr = PTR_TO_CORDB_ADDRESS(ptr); + VMPTR_This t; + t.m_addr = PTR_TO_CORDB_ADDRESS(ptr); + return t; } // This will get the raw underlying target pointer. @@ -700,15 +705,6 @@ class MSLAYOUT VMPTR_Base return reinterpret_cast((TADDR)m_addr); } - // Convenience for converting TTargetPtr --> VMPTR - static VMPTR_This MakePtr(TTargetPtr * ptr) - { - VMPTR_This t; - t.SetRawPtr(ptr); - return t; - } - - #else // // Case 3: Used in RS. Opaque handles only. @@ -1191,7 +1187,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); { LIMITED_METHOD_DAC_CONTRACT; FramePointer fp; - fp.m_sp = sp; + fp.m_sp = PTR_TO_CORDB_ADDRESS(sp); return fp; } @@ -1215,7 +1211,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); // CordbChain are really FramePointers. LPVOID GetSPValue() const { - return m_sp; + return CORDB_ADDRESS_TO_PTR(m_sp); } @@ -1226,7 +1222,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); FramePointer &operator=(BYTE* sp); FramePointer &operator=(const BYTE* sp); - LPVOID m_sp; + Portable m_sp; }; // For non-IA64 platforms, we use stack pointers as frame pointers. @@ -1457,8 +1453,8 @@ struct MSLAYOUT DebuggerIPCE_BasicTypeData { Portable elementType; Portable metadataToken; - VMPTR_Assembly vmAssembly; - VMPTR_TypeHandle vmTypeHandle; + Portable vmAssembly; + Portable vmTypeHandle; }; // DebuggerIPCE_ExpandedTypeData contains more information showing further @@ -1492,8 +1488,8 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData struct MSLAYOUT { Portable metadataToken; - VMPTR_Assembly vmAssembly; - VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments + Portable vmAssembly; + Portable typeHandle; // if non-null then further fetches will be needed to get type arguments } ClassTypeData; // used for E_T_PTR, E_T_BYREF etc. @@ -1874,8 +1870,8 @@ struct MSLAYOUT DebuggerIPCEvent Portable type; Portable processId; Portable threadId; - VMPTR_AppDomain vmAppDomain; - VMPTR_Thread vmThread; + Portable vmAppDomain; + Portable vmThread; Portable hr; Portable replyRequired; @@ -1887,32 +1883,32 @@ struct MSLAYOUT DebuggerIPCEvent { // Module whose metadata is being updated // This tells the RS that the metadata for that module has become invalid. - VMPTR_Assembly vmAssembly; + Portable vmAssembly; } MetadataUpdateData; struct MSLAYOUT { // Handle to CLR's internal appdomain object. - VMPTR_AppDomain vmAppDomain; + Portable vmAppDomain; } AppDomainData; struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; } AssemblyData; // Debug event that a module has been loaded struct MSLAYOUT { // Module that was just loaded. - VMPTR_Assembly vmAssembly; + Portable vmAssembly; }LoadModuleData; struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; LSPTR_ASSEMBLY debuggerAssemblyToken; } UnloadModuleData; @@ -1921,14 +1917,14 @@ struct MSLAYOUT DebuggerIPCEvent // Queury PDB from OOP struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; } UpdateModuleSymsData; struct MSLAYOUT { LSPTR_BREAKPOINT breakpointToken; Portable funcMetadataToken; - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable isIL; Portable offset; Portable encVersion; @@ -2026,33 +2022,33 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { Portable classMetadataToken; - VMPTR_Assembly vmAssembly; + Portable vmAssembly; LSPTR_ASSEMBLY classDebuggerAssemblyToken; } LoadClass; struct MSLAYOUT { Portable classMetadataToken; - VMPTR_Assembly vmAssembly; + Portable vmAssembly; LSPTR_ASSEMBLY classDebuggerAssemblyToken; } UnloadClass; struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable flag; } SetClassLoad; struct MSLAYOUT { - VMPTR_OBJECTHANDLE vmExceptionHandle; + Portable vmExceptionHandle; Portable firstChance; Portable continuable; } Exception; struct MSLAYOUT { - VMPTR_Thread vmThreadToken; + Portable vmThreadToken; } ClearException; struct MSLAYOUT @@ -2069,10 +2065,10 @@ struct MSLAYOUT DebuggerIPCEvent { Portable startAddress; Portable fCanSetIPOnly; - VMPTR_Thread vmThreadToken; - VMPTR_Assembly vmAssembly; + Portable vmThreadToken; + Portable vmAssembly; Portable mdMethod; - VMPTR_MethodDesc vmMethodDesc; + Portable vmMethodDesc; Portable offset; Portable fIsIL; } SetIP; // this is also used for CanSetIP @@ -2096,7 +2092,7 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { // assembly for the domain in which the notification occurred - VMPTR_Assembly vmAssembly; + Portable vmAssembly; // metadata token for the type of the CustomNotification object's type Portable classToken; @@ -2104,7 +2100,7 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - VMPTR_Thread vmThreadToken; + Portable vmThreadToken; Portable debugState; } SetAllDebugState; @@ -2124,9 +2120,9 @@ struct MSLAYOUT DebuggerIPCEvent Portable resultAddr; // AppDomain that the result is in. - VMPTR_AppDomain vmAppDomain; + Portable vmAppDomain; - VMPTR_OBJECTHANDLE vmObjectHandle; + Portable vmObjectHandle; DebuggerIPCE_ExpandedTypeData resultType; } FuncEvalComplete; @@ -2148,21 +2144,21 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { Portable objectRefAddress; - VMPTR_OBJECTHANDLE vmObjectHandle; + Portable vmObjectHandle; Portable newReference; } SetReference; struct MSLAYOUT { Portable eventType; - VMPTR_AppDomain vmAppDomain; - VMPTR_Thread vmThread; + Portable vmAppDomain; + Portable vmThread; } NameChange; // EnC Remap opportunity struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable funcMetadataToken; // methodDef of function with remap opportunity Portable currentVersionNumber; // version currently executing Portable resumeVersionNumber; // latest version @@ -2174,7 +2170,7 @@ struct MSLAYOUT DebuggerIPCEvent // EnC Remap has taken place struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable funcMetadataToken; // methodDef of function that was remapped } EnCRemapComplete; @@ -2182,7 +2178,7 @@ struct MSLAYOUT DebuggerIPCEvent // specific edit made by EnC (function add/update or field add). struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable memberMetadataToken; // Either a methodDef token indicating the function that // was updated/added, or a fieldDef token indicating the // field which was added. @@ -2203,7 +2199,7 @@ struct MSLAYOUT DebuggerIPCEvent // @todo - Perhaps we can bundle these up so we can set multiple funcs w/ 1 event? struct MSLAYOUT { - VMPTR_Assembly vmAssembly; + Portable vmAssembly; Portable funcMetadataToken; Portable dwStatus; } SetJMCFunctionStatus; @@ -2216,13 +2212,13 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - VMPTR_OBJECTHANDLE vmObjectHandle; + Portable vmObjectHandle; } CreateHandleResult; // used in DB_IPCE_DISPOSE_HANDLE event struct MSLAYOUT { - VMPTR_OBJECTHANDLE vmObjectHandle; + Portable vmObjectHandle; Portable handleType; } DisposeHandle; @@ -2232,7 +2228,7 @@ struct MSLAYOUT DebuggerIPCEvent Portable nOffset; Portable eventType; Portable dwFlags; - VMPTR_OBJECTHANDLE vmExceptionHandle; + Portable vmExceptionHandle; } ExceptionCallback2; struct MSLAYOUT @@ -2243,13 +2239,13 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - VMPTR_Thread vmThreadToken; + Portable vmThreadToken; FramePointer frameToken; } InterceptException; struct MSLAYOUT { - VMPTR_Module vmModule; + Portable vmModule; Portable pMetadataStart; Portable nMetadataSize; } MetadataUpdateRequest; diff --git a/src/coreclr/inc/dbgportable.h b/src/coreclr/inc/dbgportable.h index 92644ec637115d..f8746b5ed7ba05 100644 --- a/src/coreclr/inc/dbgportable.h +++ b/src/coreclr/inc/dbgportable.h @@ -129,6 +129,43 @@ class Portable #endif // DBG_BYTE_SWAP_REQUIRED } + // Forwarders to T's methods. Each one goes through operator=/operator T(). + // Each is templated (or has a Dummy default) so it isn't instantiated for T's that don't define + // the underlying method (e.g. Portable). Intended to be used for Portable. + template + void SetRawPtr(TPtr * ptr) + { + *this = T::MakePtr(ptr); + } + + template + auto GetRawPtr() -> decltype(Dummy().GetRawPtr()) + { + Dummy tmp = *this; + return tmp.GetRawPtr(); + } + + template + auto GetDacPtr() -> decltype(Dummy().GetDacPtr()) + { + Dummy tmp = *this; + return tmp.GetDacPtr(); + } + + template + void SetDacTargetPtr(TAddr addr) + { + T tmp; + tmp.SetDacTargetPtr(addr); + *this = tmp; + } + + bool IsNull() + { + T tmp = *this; + return tmp.IsNull(); + } + private: #ifdef DBG_BYTE_SWAP_REQUIRED // Big endian helper routine to swap the order of bytes of an arbitrary sized type From c999fe65c14f1a419b902b2a48bb69be882b6038 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 11 May 2026 18:13:17 -0700 Subject: [PATCH 2/7] remove static assert --- src/coreclr/debug/inc/dbgipcevents.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index b69bb36687d1d4..0a88639262f5fe 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1230,9 +1230,6 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); #define LEAF_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)NULL) #define ROOT_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)-1) -static_assert(sizeof(FramePointer) == sizeof(void*)); - - inline bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2) { return (fp1.m_sp < fp2.m_sp); From 0e7490ad1d07c96f13f5b29c298e730c7f05f49b Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 11 May 2026 20:52:35 -0700 Subject: [PATCH 3/7] missed a few of these --- src/coreclr/debug/inc/dbgipcevents.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 0a88639262f5fe..27a0106b84b157 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1932,18 +1932,18 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { Portable funcMetadataToken; - VMPTR_Module pModule; + Portable pModule; } DisableOptData; struct MSLAYOUT { Portable enableEvents; - VMPTR_Object vmObj; + Portable vmObj; } ForceCatchHandlerFoundData; struct MSLAYOUT { - VMPTR_Module vmModule; + Portable vmModule; Portable classMetadataToken; Portable Enabled; } CustomNotificationData; @@ -1962,7 +1962,7 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { LSPTR_STEPPER stepperToken; - VMPTR_Thread vmThreadToken; + Portable vmThreadToken; FramePointer frameToken; Portable stepIn; Portable rangeIL; @@ -2002,7 +2002,7 @@ struct MSLAYOUT DebuggerIPCEvent // Apply an EnC edit struct MSLAYOUT { - VMPTR_Assembly vmAssembly; // Module to edit + Portable 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 From 3d40896230d11448249db37189da5b401330034e Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 12 May 2026 06:40:46 -0700 Subject: [PATCH 4/7] missed another --- src/coreclr/debug/inc/dbgipcevents.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 27a0106b84b157..954d3c1cf3d16e 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1506,7 +1506,7 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData // used for E_T_FNPTR struct MSLAYOUT { - VMPTR_TypeHandle typeHandle; // if non-null then further fetches needed to get type arguments + Portable typeHandle; // if non-null then further fetches needed to get type arguments } NaryTypeData; }; From c082e90960a43a6103663cac5f892572343479be Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 12 May 2026 17:04:44 -0700 Subject: [PATCH 5/7] reverting framepointer --- src/coreclr/debug/di/breakpoint.cpp | 8 ++++---- src/coreclr/debug/di/process.cpp | 4 ++-- src/coreclr/debug/di/rsthread.cpp | 2 +- src/coreclr/debug/ee/debugger.cpp | 14 +++++++------- src/coreclr/debug/inc/dbgipcevents.h | 13 ++++++++----- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/coreclr/debug/di/breakpoint.cpp b/src/coreclr/debug/di/breakpoint.cpp index 7ab55940df3c10..943c0617db58e1 100644 --- a/src/coreclr/debug/di/breakpoint.cpp +++ b/src/coreclr/debug/di/breakpoint.cpp @@ -522,11 +522,11 @@ HRESULT CordbStepper::StepRange(BOOL fStepIn, if (m_frame == NULL) { - pEvent->StepData.frameToken = LEAF_MOST_FRAME; + pEvent->StepData.frameToken = (CORDB_ADDRESS)0; } else { - pEvent->StepData.frameToken = m_frame->GetFramePointer(); + pEvent->StepData.frameToken = PTR_TO_CORDB_ADDRESS(m_frame->GetFramePointer().GetSPValue()); } pEvent->StepData.stepIn = (fStepIn != 0); @@ -688,11 +688,11 @@ HRESULT CordbStepper::StepOut() if (m_frame == NULL) { - pEvent->StepData.frameToken = LEAF_MOST_FRAME; + pEvent->StepData.frameToken = (CORDB_ADDRESS)0; } else { - pEvent->StepData.frameToken = m_frame->GetFramePointer(); + pEvent->StepData.frameToken = PTR_TO_CORDB_ADDRESS(m_frame->GetFramePointer().GetSPValue()); } pEvent->StepData.totalRangeCount = 0; diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index b779b5a990727c..6e8a44264b0569 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -5580,7 +5580,7 @@ void CordbProcess::RawDispatchEvent( { STRESS_LOG4(LF_CORDB, LL_INFO100, "RCET::DRCE: Exception2 0x%p 0x%X 0x%X 0x%X\n", - pEvent->ExceptionCallback2.framePointer.GetSPValue(), + CORDB_ADDRESS_TO_PTR(pEvent->ExceptionCallback2.framePointer), pEvent->ExceptionCallback2.nOffset, pEvent->ExceptionCallback2.eventType, pEvent->ExceptionCallback2.dwFlags @@ -5602,7 +5602,7 @@ void CordbProcess::RawDispatchEvent( // RSSmartPtr pFrame; - FramePointer fp = pEvent->ExceptionCallback2.framePointer; + FramePointer fp = FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(pEvent->ExceptionCallback2.framePointer)); if (fp != LEAF_MOST_FRAME) { // The interface forces us to pass a FramePointer via an ICorDebugFrame. diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index fe1bab685a1252..6f58dc6e49be47 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -2184,7 +2184,7 @@ HRESULT CordbThread::InterceptCurrentException(ICorDebugFrame * pFrame) GetProcess()->InitIPCEvent(&event, DB_IPCE_INTERCEPT_EXCEPTION, true, VMPTR_AppDomain::NullPtr()); event.InterceptException.vmThreadToken = m_vmThreadToken; - event.InterceptException.frameToken = pRealFrame->GetFramePointer(); + event.InterceptException.frameToken = PTR_TO_CORDB_ADDRESS(pRealFrame->GetFramePointer().GetSPValue()); hr = GetProcess()->m_cordb->SendIPCEvent(GetProcess(), &event, sizeof(DebuggerIPCEvent)); diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index eb4dcc566fa392..7a353440588e9b 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -7158,7 +7158,7 @@ HRESULT Debugger::SendExceptionHelperAndBlock( // InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread); - ipce->ExceptionCallback2.framePointer = framePointer; + ipce->ExceptionCallback2.framePointer = PTR_TO_CORDB_ADDRESS(framePointer.GetSPValue()); ipce->ExceptionCallback2.eventType = eventType; ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = dwFlags; @@ -7311,7 +7311,7 @@ void Debugger::SendExceptionEventsWorker( InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread); - ipce->ExceptionCallback2.framePointer = framePointer; + ipce->ExceptionCallback2.framePointer = PTR_TO_CORDB_ADDRESS(framePointer.GetSPValue()); ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_USER_FIRST_CHANCE; ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = fIsInterceptable ? DEBUG_EXCEPTION_CAN_BE_INTERCEPTED : 0; @@ -7970,7 +7970,7 @@ void Debugger::SendCatchHandlerFound( // InitIPCEvent(ipce, DB_IPCE_EXCEPTION_CALLBACK2, pThread); - ipce->ExceptionCallback2.framePointer = fp; + ipce->ExceptionCallback2.framePointer = PTR_TO_CORDB_ADDRESS(fp.GetSPValue()); ipce->ExceptionCallback2.eventType = DEBUG_EXCEPTION_CATCH_HANDLER_FOUND; ipce->ExceptionCallback2.nOffset = (UINT)nOffset; ipce->ExceptionCallback2.dwFlags = dwFlags; @@ -10292,7 +10292,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) LOG((LF_CORDB,LL_INFO10000, "D::HIPCE: frame SP:%p " "StepIn:%s RangeIL:%s RangeCount:%u MapStop:0x%x " "InterceptStop:0x%x AppD:%p\n", - pEvent->StepData.frameToken.GetSPValue(), + CORDB_ADDRESS_TO_PTR(pEvent->StepData.frameToken), (pEvent->StepData.stepIn ? "true" : "false"), (pEvent->StepData.rangeIL ? "true" : "false"), pEvent->StepData.rangeCount, @@ -10348,7 +10348,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) _ASSERTE(cRanges == 0 || ((cRanges > 0) && (cRanges == pEvent->StepData.rangeCount))); - if (!pStepper->Step(pEvent->StepData.frameToken, + if (!pStepper->Step(FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(pEvent->StepData.frameToken)), pEvent->StepData.stepIn, &(pEvent->StepData.range), cRanges, @@ -10422,7 +10422,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) // Safe to stack trace b/c we're stopped. StackTraceTicket ticket(pThread); - pStepper->StepOut(pEvent->StepData.frameToken, ticket); + pStepper->StepOut(FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(pEvent->StepData.frameToken)), ticket); pIPCResult->StepData.stepperToken.Set(pStepper); } @@ -11107,7 +11107,7 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event) // // Now start processing the parameters from the event. // - FramePointer targetFramePointer = event->InterceptException.frameToken; + FramePointer targetFramePointer = FramePointer::MakeFramePointer(CORDB_ADDRESS_TO_PTR(event->InterceptException.frameToken)); ControllerStackInfo csi; diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 954d3c1cf3d16e..fb00958c5f5980 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1187,7 +1187,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); { LIMITED_METHOD_DAC_CONTRACT; FramePointer fp; - fp.m_sp = PTR_TO_CORDB_ADDRESS(sp); + fp.m_sp = sp; return fp; } @@ -1222,7 +1222,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); FramePointer &operator=(BYTE* sp); FramePointer &operator=(const BYTE* sp); - Portable m_sp; + LPVOID m_sp; }; // For non-IA64 platforms, we use stack pointers as frame pointers. @@ -1230,6 +1230,9 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); #define LEAF_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)NULL) #define ROOT_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)-1) +static_assert(sizeof(FramePointer) == sizeof(void*)); + + inline bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2) { return (fp1.m_sp < fp2.m_sp); @@ -1963,7 +1966,7 @@ struct MSLAYOUT DebuggerIPCEvent { LSPTR_STEPPER stepperToken; Portable vmThreadToken; - FramePointer frameToken; + Portable frameToken; Portable stepIn; Portable rangeIL; Portable IsJMCStop; @@ -2221,7 +2224,7 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { - FramePointer framePointer; + Portable framePointer; Portable nOffset; Portable eventType; Portable dwFlags; @@ -2237,7 +2240,7 @@ struct MSLAYOUT DebuggerIPCEvent struct MSLAYOUT { Portable vmThreadToken; - FramePointer frameToken; + Portable frameToken; } InterceptException; struct MSLAYOUT From c89aae656da730e7b7e2840e649f7659850a02bc Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 13 May 2026 16:47:36 -0700 Subject: [PATCH 6/7] copilolt comments --- src/coreclr/inc/dbgportable.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/coreclr/inc/dbgportable.h b/src/coreclr/inc/dbgportable.h index f8746b5ed7ba05..f1e829d0a869e7 100644 --- a/src/coreclr/inc/dbgportable.h +++ b/src/coreclr/inc/dbgportable.h @@ -139,14 +139,14 @@ class Portable } template - auto GetRawPtr() -> decltype(Dummy().GetRawPtr()) + auto GetRawPtr() const -> decltype(Dummy().GetRawPtr()) { Dummy tmp = *this; return tmp.GetRawPtr(); } template - auto GetDacPtr() -> decltype(Dummy().GetDacPtr()) + auto GetDacPtr() const -> decltype(Dummy().GetDacPtr()) { Dummy tmp = *this; return tmp.GetDacPtr(); @@ -160,9 +160,10 @@ class Portable *this = tmp; } - bool IsNull() + template + auto IsNull() const -> decltype(Dummy().IsNull()) { - T tmp = *this; + Dummy tmp = *this; return tmp.IsNull(); } From 05762c69bf7bdcd4dd56f4cc5db644a253838587 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Mon, 18 May 2026 10:50:54 -0700 Subject: [PATCH 7/7] code review --- src/coreclr/debug/inc/dbgipcevents.h | 6 +++--- src/coreclr/inc/dbgportable.h | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index fb00958c5f5980..0564ac6869b5ed 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -1211,7 +1211,7 @@ friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2); // CordbChain are really FramePointers. LPVOID GetSPValue() const { - return CORDB_ADDRESS_TO_PTR(m_sp); + return m_sp; } @@ -1656,11 +1656,11 @@ struct MSLAYOUT DebuggerIPCE_FuncEvalArgData // struct MSLAYOUT DebuggerIPCE_FuncEvalInfo { - VMPTR_Thread vmThreadToken; + Portable vmThreadToken; Portable funcEvalType; Portable funcMetadataToken; Portable funcClassMetadataToken; - VMPTR_Assembly vmAssembly; + Portable vmAssembly; RSPTR_CORDBEVAL funcEvalKey; Portable evalDuringException; diff --git a/src/coreclr/inc/dbgportable.h b/src/coreclr/inc/dbgportable.h index f1e829d0a869e7..3dc08064f48100 100644 --- a/src/coreclr/inc/dbgportable.h +++ b/src/coreclr/inc/dbgportable.h @@ -132,8 +132,8 @@ class Portable // Forwarders to T's methods. Each one goes through operator=/operator T(). // Each is templated (or has a Dummy default) so it isn't instantiated for T's that don't define // the underlying method (e.g. Portable). Intended to be used for Portable. - template - void SetRawPtr(TPtr * ptr) + template + auto SetRawPtr(TPtr * ptr) -> decltype(Dummy::MakePtr(ptr), void()) { *this = T::MakePtr(ptr); } @@ -152,10 +152,10 @@ class Portable return tmp.GetDacPtr(); } - template - void SetDacTargetPtr(TAddr addr) + template + auto SetDacTargetPtr(TAddr addr) -> decltype(Dummy().SetDacTargetPtr(addr)) { - T tmp; + Dummy tmp; tmp.SetDacTargetPtr(addr); *this = tmp; }