Make GetMethodInfo work for non-jit'ed code#1358
Open
leculver wants to merge 5 commits intomicrosoft:mainfrom
Open
Make GetMethodInfo work for non-jit'ed code#1358leculver wants to merge 5 commits intomicrosoft:mainfrom
leculver wants to merge 5 commits intomicrosoft:mainfrom
Conversation
…t#1306) GetMethodInfo in DacMethodLocator unconditionally required GetCodeHeaderData to succeed, which fails for methods that haven't been JIT compiled (e.g., struct unboxing stubs, un-jitted inherited methods). This fix separates the GetMethodDescData call from the GetCodeHeaderData call and handles the case where native code is not available by returning a MethodInfo with CompilationType.None and default HotColdRegions.
…icrosoft#1306) Add two test cases to MethodTests.cs: - GetMethodByHandle_StructImplementingInterface_FindsAllMethods: verifies all methods on a struct implementing an interface can be resolved via GetMethodByHandle, including unboxing stubs and inherited un-jitted methods. - StructMethodCompilationType_MatchesJitStatus: verifies un-jitted methods return CompilationType.None while JIT-compiled methods return non-None. Supporting changes: - SharedLibrary.cs: add IStructTest interface and StructWithInterface struct - Types.cs: exercise struct interface dispatch to create unboxing stub
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes ClrRuntime.GetMethodByHandle resolution for method handles whose MethodDesc exists but which don’t have code header data available (commonly for non-JIT’ed methods and some stubs), by no longer requiring GetCodeHeaderData to succeed in order to return MethodInfo. It also adds a regression scenario and tests around struct interface dispatch to cover issue #1306.
Changes:
- Update
DacMethodLocator.GetMethodInfoto succeed whenGetMethodDescDatasucceeds even if code header/native code data is unavailable, returningCompilationType.None+ defaultHotColdRegionsin that case. - Extend the
Typestest target and shared test library to exercise struct interface dispatch (unboxing stub scenario). - Add regression tests validating
GetMethodByHandlecan resolve methods for a struct implementing an interface, and asserting compilation-type behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/Microsoft.Diagnostics.Runtime/DacImplementation/DacMethodLocator.cs | Decouples MethodDesc lookup from code header lookup; returns a usable MethodInfo even when native code metadata can’t be read. |
| src/Microsoft.Diagnostics.Runtime.Tests/src/MethodTests.cs | Adds regression tests for struct/interface method handle resolution and compilation-type expectations. |
| src/TestTargets/Types/Types.cs | Triggers struct interface dispatch in the dump target to reproduce issue conditions. |
| src/TestTargets/Shared/SharedLibrary.cs | Adds IStructTest and StructWithInterface used by the new dump/test scenario. |
src/Microsoft.Diagnostics.Runtime/DacImplementation/DacMethodLocator.cs
Outdated
Show resolved
Hide resolved
…ocator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…est (issue microsoft#935) DacMethodLocator.GetMethodInfo: when HasNativeCode==0, fall back to GetMethodTableSlot + GetCodeHeaderData to resolve JIT info for methods whose per-instantiation MethodDesc lacks NativeCodeAddr (ref-type generic type instantiations sharing canonical code). Test target: stores per-instantiation MethodDesc handles for GenericClass<bool,int,float,string,object>.Invoke and Echo<string> via RuntimeHelpers.PrepareMethod + MethodHandle.Value. Test: GetMethodByHandle_GenericMethodWithRefType_ReturnsJittedInfo reads the stored handle and verifies CompilationType and HotSize. Note: on .NET Framework dumps HasNativeCode is already set for per-instantiation MethodDescs so the fallback path is not exercised. Full coverage requires .NET Core dumps (to be tested on Linux).
…sues microsoft#935, microsoft#1306) - Add RefGenericClass<T> to exercise ref-type generic instantiation sharing - Add Echo<int> MethodDesc storage for issue microsoft#935 exact scenario - Add test GetMethodByHandle_ValueTypeGenericMethod_ReturnsJittedInfo - Add test GetMethodByHandle_RefTypeGenericInstantiation_ResolvesAllMethods - Verified on Linux (.NET 10 Core): 6 MethodTests pass, 3 skipped
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.
Fix
GetMethodByHandlefor struct methods and generic method instantiationsProblem
GetMethodByHandlehad two related bugs inDacMethodLocator.GetMethodInfo:Struct methods returned
null(Get ClrMethod from virtual method of struct #1306): The old code unconditionally calledGetCodeHeaderData(NativeCodeAddr)in the same conditional asGetMethodDescData. WhenHasNativeCode == 0(unboxing stubs, un-jitted inherited methods likeToString/Equals/GetHashCode),NativeCodeAddris 0 andGetCodeHeaderDatafails, causingGetMethodInfoto returnfalse— which madeGetMethodByHandlereturnnull.Value-type generic method instantiations reported wrong compilation info (Missing some compilation information for generic methods #935): For methods like
Echo<int>(), the old code's slot-based lookup viaGetMethodTableSlotreturned the generic method definition (uninstantiated stub) instead of the JIT'd instantiation, yieldingCompilationType=NoneandHotSize=0even though WinDbg's!DumpMDcorrectly shows the method as jitted. The reporter's own investigation confirmed thatGetCodeHeaderData(NativeCodeAddr)returns the correct data while the slot-based path does not.Fix
Restructured
GetMethodInfointo a three-tier approach:Primary path (
HasNativeCode != 0): UseGetCodeHeaderData(NativeCodeAddr)to get the correct JIT type and code size. This handles all jitted methods including value-type generic instantiations (the Missing some compilation information for generic methods #935 scenario).Slot-based fallback (
HasNativeCode == 0but slot has code): TryGetMethodTableSlot+GetCodeHeaderData(slot). This is a defensive path for cases where a per-instantiation MethodDesc hasHasNativeCode=0but the method table slot points to shared JIT'd code (e.g., reference-type generic instantiations sharing code via__Canon).No native code: Return
CompilationType.Nonewith defaultHotColdRegionsfor methods that genuinely haven't been JIT compiled.Tests
Six new regression tests covering both issues:
GetMethodByHandle_StructImplementingInterface_FindsAllMethodsStructWithInterfaceresolve viaGetMethodByHandle(#1306)StructMethodCompilationType_MatchesJitStatusCompilationType(#1306)GetMethodByHandle_ValueTypeGenericMethod_ReturnsJittedInfoEcho<int>()reportsCompilationType=Jitand non-zeroHotSize(#935 exact scenario)GetMethodByHandle_GenericMethodWithRefType_ReturnsJittedInfoGenericClass<bool,int,float,string,object>.Invokeresolves correctly (#935)GetMethodByHandle_RefTypeGenericInstantiation_ResolvesAllMethodsAll tests pass on both Windows (.NET Framework dumps) and Linux (.NET Core 10 dumps).
Fixes #1306. Fixes #935. (CompilationType and HotSize; the Name truncation sub-issue is tracked separately.)