Fix cross-bitness dump reading: replace IntPtr.Size with target PointerSize#1421
Merged
max-charlamb merged 2 commits intomicrosoft:mainfrom Apr 17, 2026
Merged
Conversation
…erSize Replace ~50 uses of IntPtr.Size (host pointer size) with the target process's PointerSize so that dumps from a different architecture can be read correctly (e.g. reading ARM64 dumps from an x64 host). Changes across 14 files: - ClrArray: array length offset, multi-dim detection, rank, element addressing - ClrObject: boxed value header offset - ClrInstanceField: field address calculation - ClrField: GetSize accepts optional pointerSize parameter - ClrException: all offset methods + stack trace parsing - ClrHeap: string offsets, alignment, min object size, GC ref scanning, finalize queue walking, MemoryCache.ReadPointer - ClrDacType: GC descriptor reading, array element type, base array offset - ClrTypeFactory: string type StaticSize - GCDesc: new constructor overload with explicit pointerSize; all internal methods converted - DacHeap: frozen segment committed start - DacThreadHelpers: IP/SP reads - CommonMemoryReader: fix ReadPointer calling AsPointer(pointerSize) which bound to the 2-arg overload treating pointerSize as offset instead of size - SpanExtensions: new 3-arg AsPointer overload (pointerSize, offset) - SigParser: pointerSize field for PeekElemTypeSize Bug fix: CommonMemoryReader.ReadPointer was calling AsPointer(pointerSize) which resolved to the 2-arg overload (span, offset), treating the pointer size as an offset. Changed to AsPointer(pointerSize, 0) to use the correct 3-arg overload. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
leculver
reviewed
Apr 15, 2026
Contributor
|
Look at these as well: clrmd/src/Microsoft.Diagnostics.Runtime/ClrEnum.cs Lines 98 to 99 in cb7cd84 Maybe AsPointer overloads should all take in a pointer size and not have any IntPtr.Size itself. It's ok to make breaking changes here if you have to. We haven't yet shipped clrmd 4 yet. |
leculver
reviewed
Apr 15, 2026
903df23 to
7e9d4d8
Compare
7e9d4d8 to
1376aee
Compare
leculver
reviewed
Apr 16, 2026
Contributor
leculver
left a comment
There was a problem hiding this comment.
A few remaining issues, but overall looks great.
6433fa5 to
96516e7
Compare
…zed reads Per review feedback from @leculver: - SpanExtensions: Remove 0-arg and 1-arg AsPointer overloads that defaulted to IntPtr.Size. The ulong-offset overload now requires explicit pointerSize. - SigParser: Remove 2-arg constructor defaulting to IntPtr.Size. All callers (ClrEnum, ClrField) now pass explicit pointer size. Remove dead code: PeekElemTypeSize method (never called). - GCDesc: Remove 1-arg constructor defaulting to IntPtr.Size. - ClrField.GetSize: Remove pointerSize=0 fallback to IntPtr.Size; parameter is now required. Updated ClrPrimitiveType caller. - MetadataImport: Remove dead _pointerSize field and GetSigFromToken method (never called externally). Simplify constructors. - ClrInstanceField.ReadPointer: Mark as internal, not public. - ClrObject.AsRuntimeType: Add braces to if clause per style. Additional fixes for host-sized target reads: - ClrDelegate: Replace Read<UIntPtr> with ReadPointer (target-pointer-aware). Replace ReadValues<UIntPtr> loop with GetObjectValue iteration. - ClrObject.AsRuntimeType: Replace ReadField<nint> with ReadPointer for m_handle/m_ptr fields. - ClrArray.GetObjectValue: Replace ReadValue<nuint> with ReadPointer to read target-sized object references. - ClrEnum: Replace *(nint*) and *(nuint*) with pointer-size-conditional reads using target PointerSize. - ClrInstanceField: Add ReadPointer method for target-pointer-aware reads. - SigParserBoundsTests: Updated to pass explicit pointer size. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
96516e7 to
bb40de6
Compare
leculver
approved these changes
Apr 17, 2026
max-charlamb
pushed a commit
to dotnet/runtime
that referenced
this pull request
Apr 17, 2026
This version includes cross-bitness dump reading support (microsoft/clrmd#1421), allowing correct reading of dumps from different architectures (e.g., ARM64 dumps from an x86 host). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replace ~50 uses of
IntPtr.Size(host pointer size) with the target process'sPointerSizeacross 14 files so that dumps from a different architecture can be read correctly (e.g. reading ARM64 dumps from an x64 host, or x86 dumps from an x64 host).Motivation
Cross-platform diagnostic scenarios (e.g. this CI pipeline) fail when reading dumps from a target with a different pointer size than the host. The root cause is that ClrMD uses
IntPtr.Sizein many places to compute object layout offsets, field addresses, GC descriptor sizes, and heap alignment — all of which must use the target's pointer size, not the host's.Changes
Files modified (14):
ClrArray.csClrObject.csClrInstanceField.csClrField.csGetSizeaccepts optionalpointerSizeparameterClrException.csClrHeap.csMemoryCache.ReadPointer(12+ locations)ClrDacType.csClrTypeFactory.csStaticSizeGCDesc.cspointerSize; all internal methods convertedDacHeap.csDacThreadHelpers.csCommonMemoryReader.csSpanExtensions.csAsPointeroverload (pointerSize,offset)SigParser.cs_pointerSizefield forPeekElemTypeSizeBug fix: CommonMemoryReader.ReadPointer
ReadPointerwas callingAsPointer(pointerSize)which resolved to the 2-arg overloadAsPointer(span, int offset), treating the pointer size as an offset. Fixed toAsPointer(pointerSize, 0)to use the correct 3-arg overload.Testing
GCRootTests.FindAllPaths— pre-existing on baseline), 4 skipWhat was NOT changed
Files using
IntPtr.Sizefor host-side purposes (correctly):CacheOptions.cs,DacDataTargetCOM.cs,WindowsProcessDataReader.cs,VTableBuilder.cs,ComCallableIUnknown.cs, cache entry classes