Repository navigation
Commit 371731c
Fix alignment of 8-byte thread statics on direct TLS path (#129749)
Fixes #129733
## Problem
`Interlocked.Increment(ref threadStaticLong)` on a `[ThreadStatic]
static long` throws `System.DataMisalignedException` on osx-arm64.
## Root cause
In `GetTLSIndexForThreadStatic` (`src/coreclr/vm/threadstatics.cpp`),
small non-collectible thread statics of already-initialized classes are
placed via a top-down bump allocator on the direct-on-thread-local-data
path. The per-field alignment was computed with a missing `else`:
```cpp
uint32_t alignment;
if (bytesNeeded >= 8)
alignment = 8;
if (bytesNeeded >= 4) // <-- missing 'else'
alignment = 4;
else if (bytesNeeded >= 2)
alignment = 2;
else
alignment = 1;
```
For an 8-byte field (`long`/`double`), the first `if` sets `alignment =
8`, but the second `if (bytesNeeded >= 4)` is also true and overwrites
it with `alignment = 4`. The offset is then chosen via
`AlignDown(indexOffsetWithoutAlignment, alignment)`, so with `alignment
== 4` it can land on a 4-mod-8 boundary. Since `ThreadLocalData` (and
thus `ExtendedDirectThreadLocalTLSData`) is only 8-byte aligned, the
resulting absolute address of the `long` can be 4-byte but not 8-byte
aligned.
## Why it only reproduces on arm64 (and intermittently)
- x64 tolerates misaligned atomic operations; arm64
`Interlocked.Increment` lowers to `ldaxr`/`stlxr`, which fault on a
misaligned address → `DataMisalignedException`.
- It is layout-dependent: whether the 4-aligned offset also happens to
be 8-aligned depends on how many bytes earlier thread statics already
consumed in the bump allocator. This is why a real app (e.g.
ASP.NET/Kestrel, which registers other thread statics first) trips it
while a trivial repro may not.
## Fix
Add the missing `else` so an 8-byte field keeps `alignment = 8`.
## Testing
I was unable to build/run locally for this change (development box is
linux-x64 while the failure manifests on osx-arm64, where misaligned
atomics fault). The fix is a one-line correction to the alignment
selection logic and was verified by source inspection. CI will exercise
the relevant platforms.
> [!NOTE]
> This pull request was authored with the assistance of GitHub Copilot.
Co-authored-by: EgorBo <egorbo@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent d1efd0b commit 371731c
1 file changed
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
738 | 738 | | |
739 | 739 | | |
740 | 740 | | |
741 | | - | |
| 741 | + | |
742 | 742 | | |
743 | 743 | | |
744 | 744 | | |
| |||
0 commit comments