Skip to content

Fix a series of possible race conditions in thread static variable initialization#127843

Open
davidwrighton wants to merge 4 commits intodotnet:mainfrom
davidwrighton:fix_thread_statics_race_conditions
Open

Fix a series of possible race conditions in thread static variable initialization#127843
davidwrighton wants to merge 4 commits intodotnet:mainfrom
davidwrighton:fix_thread_statics_race_conditions

Conversation

@davidwrighton
Copy link
Copy Markdown
Member

  • The two critical ones are the one just after the memcpy in the TLSIndexToMethodTableMap, as well as the VolatileStore when setting pIndex.

Fixes #127776

…itialization

- The two critical ones are the one just after the memcpy in the TLSIndexToMethodTableMap, as well as the VolatileStore when setting pIndex.

Fixes dotnet#127776
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
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

This PR targets a set of suspected race conditions in CoreCLR thread-static infrastructure by strengthening publication/visibility guarantees when updating TLS index metadata and the TLSIndex→MethodTable map. This aligns with the reported intermittent macOS arm64 crash in GetThreadLocalStaticBase by ensuring readers can’t observe partially-published state during concurrent thread-static access.

Changes:

  • Use VolatileStore when publishing a resized TLSIndexToMethodTableMap (pMap and m_maxIndex) to ensure the copied/initialized map contents are visible before other threads observe the updated pointers/sizes.
  • Use VolatileStore when writing/clearing individual map entries to prevent reordering and improve cross-thread visibility of per-index updates.
  • Use VolatileStore when publishing the newly allocated TLSIndex (*pIndex) so other threads that observe the allocated index have the intended ordering/visibility for preceding writes on the allocation path.

Copilot AI review requested due to automatic review settings May 7, 2026 21:57
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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread src/coreclr/vm/threadstatics.h Outdated
Comment thread src/coreclr/vm/threadstatics.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 7, 2026 23:58
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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

static TLSIndex Unallocated() { LIMITED_METHOD_DAC_CONTRACT; return TLSIndex(0xFFFFFFFF); }
bool operator == (TLSIndex index) const { LIMITED_METHOD_DAC_CONTRACT; return TLSIndexRawIndex == index.TLSIndexRawIndex; }
bool operator != (TLSIndex index) const { LIMITED_METHOD_DAC_CONTRACT; return TLSIndexRawIndex != index.TLSIndexRawIndex; }
void VolatileStore(const TLSIndex &other) { LIMITED_METHOD_CONTRACT; ::VolatileStore(&TLSIndexRawIndex, other.TLSIndexRawIndex); }
Comment on lines 771 to 776
g_pThreadStaticCollectibleTypeIndices->Set(newTLSIndex, pMT, gcStatic);
pMT->GetLoaderAllocator()->GetTLSIndexList().Append(newTLSIndex);
}

*pIndex = newTLSIndex;
pIndex->VolatileStore(newTLSIndex); // Use a volatile store so that any other thread that sees the allocated index will also see the writes throughout this path.
}
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.

Intermittent SIGSEGV in GetThreadLocalStaticBase on macOS arm64

2 participants