Skip to content

[cDAC] Fix method table slot lookup #115057

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2025

Conversation

max-charlamb
Copy link
Contributor

Found this bug while testing EnumMethodInstancesByAddress.

MethodTable slots are pointer sized. Finding the correct one is done using pointer arithmetic on the native code but has to be done explicitly on the cDAC.

@Copilot Copilot AI review requested due to automatic review settings April 25, 2025 18:31
@ghost ghost added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Apr 25, 2025
@max-charlamb max-charlamb requested a review from a team April 25, 2025 18:31
Copy link
Contributor

@Copilot 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 fixes a critical bug in the pointer arithmetic for method table slot lookup in the cDAC runtime type system.

  • Correctly adjusts the pointer arithmetic by multiplying the offset with _target.PointerSize
  • Ensures that the calculation accounts for pointer-sized slots
Comments suppressed due to low confidence (1)

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs:846

  • The change correctly applies multiplication by _target.PointerSize to adjust for pointer-sized slots. Ensure that _target.PointerSize is always valid and consistent across different target environments to avoid potential underflow or miscalculation.
return nonVirtualSlotsArray - ((1 + (slotNum - mt.NumVirtuals)) * (ulong)_target.PointerSize);

@max-charlamb max-charlamb added area-Diagnostics-coreclr and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Apr 25, 2025
Copy link
Contributor

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

@kg
Copy link
Member

kg commented Apr 25, 2025

Is this a pattern that occurs in other places? It might be worth considering having a TargetManagedPointer that behaves the same as IntPtr* does, i.e. +1 moves to the next managed pointer, or omitting operators that are likely to indicate the caller is doing the wrong thing.

@@ -843,7 +843,7 @@ private TargetPointer GetAddressOfSlot(TypeHandle typeHandle, uint slotNum)
TargetPointer auxDataPtr = mt.AuxiliaryData;
Data.MethodTableAuxiliaryData auxData = _target.ProcessedData.GetOrAdd<Data.MethodTableAuxiliaryData>(auxDataPtr);
TargetPointer nonVirtualSlotsArray = auxDataPtr + (ulong)auxData.OffsetToNonVirtualSlots;
return nonVirtualSlotsArray - (1 + (slotNum - mt.NumVirtuals));
return nonVirtualSlotsArray - ((1 + (slotNum - mt.NumVirtuals)) * (ulong)_target.PointerSize);
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to see (1 + (slotNum - mt.NumVirtuals)) in a separate named local that describes what it is, so the index calculation is separated from the machinery of turning an index into an address

@max-charlamb
Copy link
Contributor Author

Is this a pattern that occurs in other places? It might be worth considering having a TargetManagedPointer that behaves the same as IntPtr* does, i.e. +1 moves to the next managed pointer, or omitting operators that are likely to indicate the caller is doing the wrong thing.

This sounds like a good idea, but the current design makes it difficult to implement.

  • TargetPointer implicitly converts to ulong. This isn't a big deal, but we would need to remove this conversion and fix existing code.
  • More impactfully, TargetPointer is just a typed ulong. It doesn't hold a reference to the actual Target or know the target's pointer size. Currently all consumers are expected to use the info stored on the Target to do any of these conversions.

Maybe we could add a method or extension to Target that allows pointer arithmetic.

@max-charlamb
Copy link
Contributor Author

Merging fix for now, will take another look at improving pointer math in the future

@max-charlamb max-charlamb merged commit 54f1fb1 into dotnet:main Apr 28, 2025
152 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators May 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants