Skip to content

[native] Fix concurrent FastTiming event storage - #12455

Merged
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-fix-fast-timing-races
Aug 20, 2026
Merged

[native] Fix concurrent FastTiming event storage#12455
jonathanpeppers merged 1 commit into
mainfrom
jonathanpeppers-fix-fast-timing-races

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Fixes #12437.

FastTiming treated reserved std::vector capacity as constructed array storage and allowed concurrent event access while reserve() moved and freed that storage. Under sustained multi-threaded typemap activity with debug.mono.log=timing, this could corrupt the heap and trigger Scudo invalid chunk state when deallocating aborts.

  • replace the reallocating vector with atomically published, never-moved raw event chunks;
  • publish completed events with release/acquire synchronization so timing dumps skip in-flight entries safely;
  • preserve low-overhead event lookup with a thread-local chunk cursor;
  • make startup state publication atomic and ensure StartupAwareLock only unlocks mutexes it acquired;
  • reclaim per-event detail strings when timing storage is destroyed;
  • add a CoreCLR MSBuildDeviceIntegration regression that generates concurrent native typemap events beyond the original 4,096-entry boundary and verifies a complete timing dump;
  • avoid introducing new libc++ container or ownership dependencies.

Validation

  • CoreCLR native runtime build
  • MonoVM native runtime build
  • MSBuildDeviceIntegration build
  • Opus 5 code review

  • Useful description of why the change is necessary.
  • Links to issues fixed
  • Unit tests

Replace the reallocating event vector with stable chunks, publish completed events safely for concurrent dumps, and fix startup-aware lock ownership. Add a CoreCLR device regression that grows and dumps fast timing events.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d40daefe-fd3f-4c2d-96d9-9c91a6b0c5c2
Copilot AI lite review requested due to automatic review settings August 19, 2026 21:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 native concurrency bug in FastTiming event storage that could corrupt the heap when timing logging is enabled under sustained multi-threaded typemap activity. It replaces the previous std::vector-backed “index into reserved capacity” approach (which could be invalidated by concurrent reserve() reallocation) with a chunked, never-moved allocation strategy and uses release/acquire publication so timing dumps can safely skip in-flight events.

Changes:

  • Replaced reallocating std::vector timing storage with atomically-linked, never-moved event chunks; added release/acquire synchronization for “event complete” publication and dump-side filtering.
  • Made startup state publication atomic and fixed StartupAwareLock so it only unlocks when it actually acquired the mutex.
  • Added a device integration regression test that forces timing storage to grow past the original 4,096-entry boundary and verifies a complete timing dump.

Reviewed changes

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

Show a summary per file
File Description
tests/MSBuildDeviceIntegration/Tests/FastTimingTests.cs New CoreCLR device test stressing concurrent typemap events past the 4,096 boundary and validating dump output.
src/native/mono/runtime-base/startup-aware-lock.hh Track lock ownership to avoid unlocking when the lock wasn’t acquired during startup.
src/native/mono/runtime-base/monodroid-state.hh Make startup_in_progress reads/writes atomic with acquire/release ordering.
src/native/common/runtime-base/timing-internal.cc Dump now skips in-flight events via acquire load of the completion flag; removes vector-realloc lock usage.
src/native/common/include/runtime-base/timing-internal.hh Introduces chunked event storage, atomic enable publication, and completion-based dump filtering.
src/native/clr/include/runtime-base/startup-aware-lock.hh Same lock-ownership fix as Mono header for CoreCLR runtime.
src/native/clr/include/runtime-base/monodroid-state.hh Same atomic startup flag change as Mono header for CoreCLR runtime.

@jonathanpeppers

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12455

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ LGTM

Findings: 0 errors · 0 warnings · 1 suggestion

The chunked storage removes the invalid vector-capacity access and preserves stable event addresses; the acquire/release publication around initialization, chunk linking, completion, and startup state is coherent. The lock-ownership fix also correctly handles startup transitioning while a guard is alive. CI is green across all 45 checks.

I left one non-blocking inline suggestion to exercise dump() while timing events are still in flight, since the current regression waits for all workers to finish before requesting the dump.

Generated by Android PR Reviewer for #12455 · gpt56 · 101.6 AIC · ⌖ 8.85 AIC · ⊞ 25.7K
Comment /review to run again

Comment thread tests/MSBuildDeviceIntegration/Tests/FastTimingTests.cs
@jonathanpeppers
jonathanpeppers merged commit 7a41092 into main Aug 20, 2026
45 checks passed
@jonathanpeppers
jonathanpeppers deleted the jonathanpeppers-fix-fast-timing-races branch August 20, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CoreCLR] FastTiming::start_event corrupts the heap when debug.mono.log=timing (Scudo "invalid chunk state when deallocating")

3 participants