Report CoreCLR Write Barriers And Code-Heap Stubs In Traces - #132190
Report CoreCLR Write Barriers And Code-Heap Stubs In Traces#132190brianrob wants to merge 13 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
There was a problem hiding this comment.
Pull request overview
This PR expands runtime symbol reporting for executable code that’s generated/allocated outside normal JITted methods, so tracing consumers can attribute those code ranges in ETW/EventPipe and PerfMap outputs. It does this by emitting helper-style method events for copied write barriers and code-heap stub/code-fragment blocks, and by improving CodeHeapIterator’s ability to surface bounded stub ranges during enumeration/rundown.
Changes:
- Add reporting/enumeration of copied write-barrier code ranges for ETW enumeration and PerfMap (including replay during method enumeration).
- Teach
CodeHeapIteratorto identify stub code blocks and provide bounded sizes + kinds for logging. - Extend the EventPipe rundown validation test to generate VSD activity and validate helper events appear in live + rundown streams.
Show a summary per file
| File | Description |
|---|---|
| src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.cs | Generates VSD activity and validates helper-style stub/write-barrier events appear in live + rundown method events. |
| src/coreclr/vm/threads.h | Renames/init entrypoint and adds declarations for copied write-barrier reporting helpers. |
| src/coreclr/vm/threads.cpp | Implements enumeration/reporting of copied write barriers to PerfMap and ETW enumeration. |
| src/coreclr/vm/perfmap.cpp | Emits copied write barriers and stub-block ranges when generating an on-demand PerfMap. |
| src/coreclr/vm/eventtrace.cpp | Extends helper event emission to support different enumeration event types and reports stub blocks + copied write barriers during enumeration. |
| src/coreclr/vm/dynamicmethod.cpp | Ensures heap list entries for host code heaps carry a loader allocator pointer for filtered iteration. |
| src/coreclr/vm/codeman.h | Adds wide-string stub-kind names, stub-kind/size accessors on CodeHeapIterator, and moves small-block threshold to a shared constant. |
| src/coreclr/vm/codeman.cpp | Updates CodeHeapIterator to snapshot heap ends, identify stub code blocks, and report stub blocks via PerfMap + ETW helper events. |
| src/coreclr/vm/ceemain.cpp | Calls the new tracing-data initializer during startup. |
| src/coreclr/inc/eventtracebase.h | Updates/moves SendHelperEvent declaration to support passing enumeration options. |
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 0
- Review effort level: Lite
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
|
/azp run runtime Note This rerun request was generated by GitHub Copilot after Build Analysis identified unrelated infrastructure timeouts and known test failures. |
|
No pipelines are associated with this pull request. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Review details
Suppressed comments (1)
src/tests/tracing/eventpipe/rundownvalidation/rundownvalidation.cs:111
- The test currently requires write-barrier helper events to be present and valid (ValidateHelperEvents(rundownWriteBarriers)), but copied write barriers are not necessarily enabled. In CoreCLR, write-barrier copying is gated by CLRConfig::UNSUPPORTED_UseGCWriteBarrierCopy and defaults to disabled (src/coreclr/vm/eeconfig.cpp:110 sets fIsWriteBarrierCopyEnabled = false; src/coreclr/vm/eeconfig.cpp:531 sets it based on the config switch). When the copy is disabled, ReportCopiedWriteBarriers* won’t emit any helper events, rundownWriteBarriers stays empty, and this test will fail on otherwise-correct builds.
Consider validating write-barrier helpers only when the events are actually present (or otherwise gating the expectation on a detectable condition).
bool hasValidCoreClrHelpers =
!PlatformDetection.IsCoreCLR ||
!RuntimeFeature.IsDynamicCodeCompiled ||
(ValidateHelperEvents(liveStubBlocks) &&
ValidateHelperEvents(rundownStubBlocks) &&
ValidateHelperEvents(rundownWriteBarriers) &&
HaveMatchingStubBlocks(liveStubBlocks, rundownStubBlocks));
- Files reviewed: 11/11 changed files
- Comments generated: 0 new
- Review effort level: Lite
|
LGTM, but I want @hoyosjs to review as well before signoff. |
| blockWriterHolder.GetRW()->m_used = 0; | ||
| blockWriterHolder.GetRW()->m_allocated = numJumps; | ||
| if (pMD && pMD->IsLCGMethod()) | ||
| blockWriterHolder.GetRW()->SetHostCodeHeap(static_cast<HostCodeHeap*>(pCodeHeap->pHeap)); |
There was a problem hiding this comment.
These LCG jump-stub blocks now receive a load event below, but LCGMethodResolver::TryDestroyCodeHeapMemory frees them without emitting an unload event.
There was a problem hiding this comment.
Thanks for pointing this out. Fixed.
| PRECONDITION(ulHelperSize != 0); | ||
| } CONTRACTL_END; | ||
|
|
||
| EX_TRY |
There was a problem hiding this comment.
Now that this is folder to SendHelperEvent - I don't see any explicit trycatch and no guard for ETW_TRACING_CATEGORY_ENABLED, so the ngen keyword (not just the jit keyword) also enable these. If anything at least a comment would help to see why this is not consistent with all other methods.
There was a problem hiding this comment.
That being said - the GC barrier and the VSD stubs to get used regardless of jit. This now feelds more correct
There was a problem hiding this comment.
You're right - I didn't intentionally remove the function that's responsible for the try/catch block. I do want to keep the tracing category check out though because we're not generating any expensive strings, and we do want these to show up regardless of which keyword (JIT or NGEN) initializes them.
I've updated the PR to fix-up the API boundary between ETW::MethodLog and the rest of the VM call sites.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec89d46-dd0a-4373-8c4b-9ccdabfdecc2
|
/ba-g Current failures are unrelated known test failures: HttpListener timeout #132336 on both Windows checked legs, browser-Wasm bestfit-finalize #132107, and browser-Wasm ContextualReflection preemptive-GC assertion #131925. The affected tests and subsystems are outside this PR's ETW/stub changes. Note This Build Analysis override rationale was generated by GitHub Copilot. |
|
@hoyosjs this one should be ready for review again. Thanks. |
Summary
Improve symbol coverage for executable code generated outside normal JIT methods. This is in response to an internal customer that is capturing traces where large percentages of symbols are unresolvable and don't resolve to a module. Upon investigation, these symbols should resolve to the copied write barrier or one of several different kinds of stubs.
Coverage
MethodUnloadVerbose,MethodDCStartVerbose, andMethodDCEndVerbose.MethodLoadVerbose.MethodUnloadVerbose,MethodDCStartVerbose, andMethodDCEndVerbose.DOTNET_PerfMapStubGranularity.On-demand PerfMap generation uses blocks because individual allocations cannot be reconstructed during enumeration.
All ETW/EventPipe entries use
JitHelperMethodmetadata.Implementation Notes
CodeHeapIteratornow snapshots each heap’s end and uses per-heap lookahead to produce bounded, non-overlapping stub ranges. Jump-stub sizes use their existing allocation metadata; other code-fragment blocks use the bounded allocation extent.Copied write-barrier reporting derives targets from the configured JIT helper table.
This does not change stub layout, allocation size, alignment,
CodeHeaderadjacency, DAC contracts, or jump reachability.Note
This pull request description was created with GitHub Copilot.