Skip to content

[release/11.0] [mono] Fix gc descriptor for large static valuetypes - #136859

Open
github-actions[bot] wants to merge 1 commit into
release/11.0from
backport/pr-136625-to-release/11.0
Open

github-actions[bot] wants to merge 1 commit into
release/11.0from
backport/pr-136625-to-release/11.0

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Backport of #136625 to release/11.0

/cc @BrzVlad

Customer Impact

  • Customer reported
  • Found internally

A large valuetype (more than 255 fields) which is stored in a static field will be incorrectly scanned by the GC on mono. This means that references stored inside this valuetype can end up with a stale value (an address to the old object location or an address to the collected object). Applications storing large valuetypes in a static field can experience random crashes or incorrect program behavior. Issue was hit by customer on blazor wasm.

Regression

  • Yes
  • No

Testing

Reproduced bug with a sample app, which was also used to validate the fix.

Risk

Low. This is a minor fix to the gc ref bitmap computation logic.

`compute_class_bitmap` has the role of initializing the incoming bitmap,
by setting bits for slots containing refs for the class in question. If
the passed bitmap is not large enough to hold bits for all slots, it
allocates a new bitmap which will be returned. `compute_class_bitmap`
also receives a position argument to offset the bit setting in the
received bitmap. All non-static field offsets include also the expected
object header size (of 2 slots). If you need to set ref bits for a
valuetype field inside a class having its bitmap computed, then you pass
the bitmap owned by this parent class and the position where the bitmap
needs to be initialized, position which needs to subtract
MONO_OBJECT_HEADER_BITS to revert the standard field offset.

Consider the bitmap initialization for the `StaticData` class from the
testcase. It will allocate a bitmap able to hold all static data for the
class, in our case only one field, therefore `sizeof(LargeValue) /
sizeof(void*)` bits. The current offset to store the bits is 0. It will
then recursively delegate the initialization of the bitmap section for
the `LargeValue` to the instance field specific part, passing the
-MONO_OBJECT_HEADER_BITS offset. The `max_size` that we compute for this
class includes the object header, so it can therefore exceed the initial
bitmap size. This would hit the realloc path which the caller doesn't
expect, ending up with improperly initialized ref bitmaps.

Fixes #136602
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@BrzVlad BrzVlad added the Servicing-consider Issue for next servicing release review label Nov 2, 2026

This branch has not been deployed

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

Labels

area-VM-meta-mono Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant