Skip to content

Change VMPTR IPC events to ensure endianness consistency#128058

Open
rcj1 wants to merge 3 commits into
dotnet:mainfrom
rcj1:vmptr-portable
Open

Change VMPTR IPC events to ensure endianness consistency#128058
rcj1 wants to merge 3 commits into
dotnet:mainfrom
rcj1:vmptr-portable

Conversation

@rcj1
Copy link
Copy Markdown
Contributor

@rcj1 rcj1 commented May 12, 2026

The inadvertent consequence of #127943 is that since VMPTR now wraps a Portable<CORDB_ADDRESS>, VMPTR is propagated as a little-endian value across DBI, DAC, and EE, as opposed to solely in the IPC layer. Changing this such that VMPTR wraps CORDB_ADDRESS and we have Portable<VMPTR> in the IPC layer - remains little-endian in IPC, but the conversion operator to a VMPTR converts it to the machine endianness.

@rcj1 rcj1 requested review from Copilot, max-charlamb and noahfalk May 12, 2026 00:44
@rcj1 rcj1 changed the title Change VMPTR IPC events to ensure endianness Change VMPTR IPC events to ensure endianness consistency May 12, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts how VMPTR values are represented across the debugger IPC boundary to preserve endianness correctness: VMPTR becomes a host-endian wrapper over CORDB_ADDRESS, and IPC payloads should carry Portable<VMPTR> so they remain little-endian “on the wire” while converting back to host endianness on access.

Changes:

  • Adds convenience forwarders on Portable<T> to call pointer-like helpers (intended for Portable<VMPTR_*>) through the endian-converting operators.
  • Changes VMPTR_Base storage from Portable<CORDB_ADDRESS> to CORDB_ADDRESS, and updates many IPC event fields from VMPTR_* to Portable<VMPTR_*>.
  • Updates a couple of event-producing sites to initialize null VMPTR values via NullPtr() assignment.
Show a summary per file
File Description
src/coreclr/inc/dbgportable.h Adds Portable<T> method forwarders intended to enable ergonomic use of Portable<VMPTR_*> fields.
src/coreclr/debug/inc/dbgipcevents.h Moves endianness handling for VMPTR from inside VMPTR_Base to the IPC layer by wrapping many IPC fields in Portable<>, and adjusts some pointer field representations.
src/coreclr/debug/ee/debugger.cpp Updates null initialization for vmAssembly in DebuggerIPCE_BasicTypeData to align with the new Portable<VMPTR_*> field type.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 3

Comment thread src/coreclr/debug/inc/dbgipcevents.h
Comment on lines +141 to +167
template <typename Dummy = T>
auto GetRawPtr() -> decltype(Dummy().GetRawPtr())
{
Dummy tmp = *this;
return tmp.GetRawPtr();
}

template <typename Dummy = T>
auto GetDacPtr() -> decltype(Dummy().GetDacPtr())
{
Dummy tmp = *this;
return tmp.GetDacPtr();
}

template <typename TAddr>
void SetDacTargetPtr(TAddr addr)
{
T tmp;
tmp.SetDacTargetPtr(addr);
*this = tmp;
}

bool IsNull()
{
T tmp = *this;
return tmp.IsNull();
}
Comment on lines +163 to +165
bool IsNull()
{
T tmp = *this;
Copilot AI review requested due to automatic review settings May 12, 2026 03:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 4

Comment on lines +142 to +149
auto GetRawPtr() -> decltype(Dummy().GetRawPtr())
{
Dummy tmp = *this;
return tmp.GetRawPtr();
}

template <typename Dummy = T>
auto GetDacPtr() -> decltype(Dummy().GetDacPtr())
Comment on lines +163 to +165
bool IsNull()
{
T tmp = *this;
Comment on lines 1486 to 1490
{
Portable<mdTypeDef> metadataToken;
VMPTR_Assembly vmAssembly;
VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments
Portable<VMPTR_Assembly> vmAssembly;
Portable<VMPTR_TypeHandle> typeHandle; // if non-null then further fetches will be needed to get type arguments
} ClassTypeData;
LPVOID m_sp;
Portable<CORDB_ADDRESS> m_sp;
};

FramePointer &operator=(const BYTE* sp);

LPVOID m_sp;
Portable<CORDB_ADDRESS> m_sp;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we left FramePointer as-is and just used Portable<CORDB_ADDRESS> in the small number of places where FramePointer currently shows up in the IPC definition? I'm trying to avoid embedding endian-swapping inside more types that are often used outside IPC events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants