Skip to content

Fix DAC GetNativeCodeInfo API to use async variant for thunk MethodDescs#126728

Open
tommcdon wants to merge 1 commit intodotnet:mainfrom
tommcdon:dev/tommcdon/fixGetNativeCodeInfo
Open

Fix DAC GetNativeCodeInfo API to use async variant for thunk MethodDescs#126728
tommcdon wants to merge 1 commit intodotnet:mainfrom
tommcdon:dev/tommcdon/fixGetNativeCodeInfo

Conversation

@tommcdon
Copy link
Copy Markdown
Member

@tommcdon tommcdon commented Apr 9, 2026

Regressed by #125900 from #124354

PR 125900 replaced GetAsyncOtherVariantNoCreate with GetOrdinaryVariantNoCreate,
but for a thunk the correct target is the async variant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tommcdon tommcdon added this to the 11.0.0 milestone Apr 9, 2026
@tommcdon tommcdon self-assigned this Apr 9, 2026
Copilot AI review requested due to automatic review settings April 9, 2026 18:58
@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

Adjusts DAC GetNativeCodeInfo to resolve async thunk MethodDescs to the correct associated implementation MethodDesc by selecting the async variant, addressing a regression introduced by changes to async thunking.

Changes:

  • Update DacDbiInterfaceImpl::GetNativeCodeInfo to use GetAsyncVariantNoCreate() when the resolved MethodDesc is an async thunk.
  • Ensure native code region/EnC info is reported for the async implementation rather than the thunk.

@max-charlamb
Copy link
Copy Markdown
Member

Should we always try to get the non-thunk variant? Regardless of if it is async or ordinary?

@tommcdon
Copy link
Copy Markdown
Member Author

tommcdon commented Apr 9, 2026

Should we always try to get the non-thunk variant? Regardless of if it is async or ordinary?

For runtime async methods, I believe FindLoadedMethodRefOrDef always resolves to an async thunk method. So if the method is identified as "async", my guess is that we need to resolve it to the async variant.

if (pMethodDesc != NULL && pMethodDesc->IsAsyncThunkMethod())
{
MethodDesc* pAsyncVariant = pMethodDesc->GetOrdinaryVariantNoCreate();
MethodDesc* pAsyncVariant = pMethodDesc->GetAsyncVariantNoCreate();
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.

Suggested change
MethodDesc* pAsyncVariant = pMethodDesc->GetAsyncVariantNoCreate();
MethodDesc* pAsyncVariant = pMethodDesc->GetAsyncOtherVariantNoCreate();

I think this is a little more general. The current code probably works too but this one doesn't require assumptions about which variant we will get from FindLoadedMethodRefOrDef in the ordinary case.

Copy link
Copy Markdown
Member

@max-charlamb max-charlamb Apr 9, 2026

Choose a reason for hiding this comment

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

I think this is a little more general. The current code probably works too but this one doesn't require assumptions about which variant we will get from FindLoadedMethodRefOrDef in the ordinary case.

I agree, we want this logic, but that exact method was removed recently (#125900).

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.

oh hah... I need to catch up it appears ;p

@max-charlamb
Copy link
Copy Markdown
Member

Should we always try to get the non-thunk variant? Regardless of if it is async or ordinary?

For runtime async methods, I believe FindLoadedMethodRefOrDef always resolves to an async thunk method. So if the method is identified as "async", my guess is that we need to resolve it to the async variant.

Okay, that seems reasonable. FindLoadedMethodRefOrDef should always return the ordinary variant given this check when adding method defs to the m_MethodDefToDescMap

 if (!pMD->IsUnboxingStub() && !pMD->IsAsyncVariantMethod())
 {
     pModule->EnsuredStoreMethodDef(pMD->GetMemberDef(), pMD);
 }

(line 2807-2809 in clsload.cpp)

This should mean that if we get into the pMethodDesc->IsAsyncThunkMethod() check, it implies that we have an ordinary thunk and getting the async method will be the true body. I am a little concerned this falls apart with EnC given that registers the methods to the map without the above check.

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.

4 participants