Skip to content

Fix P/Invoke IL stub race in DoPrestub#124579

Open
AaronRobinsonMSFT wants to merge 7 commits intodotnet:mainfrom
AaronRobinsonMSFT:fix-pinvoke-stub-race
Open

Fix P/Invoke IL stub race in DoPrestub#124579
AaronRobinsonMSFT wants to merge 7 commits intodotnet:mainfrom
AaronRobinsonMSFT:fix-pinvoke-stub-race

Conversation

@AaronRobinsonMSFT
Copy link
Member

Summary

Re-enable ILStubCache lookup/insert for forward P/Invoke stubs to prevent racing threads from independently creating and JIT-ing duplicate IL stubs for the same target method.

Root Cause

PR #117901 made IsSharedStubScenario return false for forward P/Invokes, which disabled the ILStubCache lookup. Multiple threads could then each create their own DynamicMethodDesc and JIT it, producing different PCODE values that violated the assert in DoPrestub.

Fix

  • Remove the forward P/Invoke exclusion from IsSharedStubScenario so these stubs use the ILStubCache for de-duplication.
  • In CreateHashBlob, create a minimal hash blob containing just the target MethodDesc pointer for forward P/Invoke stubs, so different P/Invoke methods get distinct cache entries while racing threads for the same method converge on the same DynamicMethodDesc.

Fixes #124530

Re-enable ILStubCache lookup/insert for forward P/Invoke stubs to
prevent racing threads from independently creating and JIT-ing
duplicate IL stubs for the same target method.

PR dotnet#117901 made IsSharedStubScenario return false for forward
P/Invokes, which disabled the cache. Multiple threads could then
each create their own DynamicMethodDesc and JIT it, producing
different PCODE values that violated the assert in DoPrestub.

The fix:
- Remove the forward P/Invoke exclusion from IsSharedStubScenario
  so these stubs use the ILStubCache for de-duplication.
- In CreateHashBlob, create a minimal hash blob containing just the
  target MethodDesc pointer for forward P/Invoke stubs, so different
  P/Invoke methods get distinct cache entries while racing threads
  for the same method converge on the same DynamicMethodDesc.

Fixes dotnet#124530

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Copy link
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 fixes a race condition in P/Invoke IL stub generation that was introduced by PR #117901. The root cause was that forward P/Invoke stubs (non-CALLI, non-vararg) were excluded from IsSharedStubScenario, disabling the ILStubCache lookup/insert mechanism. This allowed multiple threads to independently create and JIT duplicate IL stubs for the same target method, resulting in different PCODE values and violating the assert in DoPrestub.

Changes:

  • Re-enables ILStubCache usage for forward P/Invoke stubs by removing their exclusion from IsSharedStubScenario
  • Creates minimal hash blobs keyed by target MethodDesc pointer for forward P/Invoke stubs to ensure proper cache de-duplication
  • Updates comments to reflect the new caching behavior

@jkoritzinsky
Copy link
Member

Could we store the DynamicMethodDesc on the PInvokeMethodDesc directly instead of going through the cache if we always have a 1:1 relationship here?

Copy link
Member

@jtschuster jtschuster left a comment

Choose a reason for hiding this comment

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

LGTM, thank you!

@AaronRobinsonMSFT
Copy link
Member Author

Could we store the DynamicMethodDesc on the PInvokeMethodDesc directly instead of going through the cache if we always have a 1:1 relationship here?

I think we could, but I really dislike the idea of having multiple places for this sort of data. Instead of hiding it on the PInvokeMethodDesc for this one instance, I would prefer to fix the entire MethodDesc heirarchy and make it less bespoke. Unless there is a compelling reason to add it there, especially since it is a single lookup cost, I'm inclined to leave it as-is.

@jkoritzinsky
Copy link
Member

Yeah this can wait until we do a greater refactoring of the MethodDesc hierarchy if that's the preference.

@jkotas
Copy link
Member

jkotas commented Feb 19, 2026

refactoring of the MethodDesc hierarchy

There should not be a DynamicMethodDesc for these in the first place. It can be all transient IL.

Copilot AI review requested due to automatic review settings February 19, 2026 14:55
Copy link
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

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings February 20, 2026 00:33
Copy link
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

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Race in PInvoke stub generation

4 participants

Comments