Repository navigation
Zero-initialize the return-value range in the Leave2 slow path - #135449
Merged
lateralusX merged 1 commit intoOct 19, 2026
Merged
Conversation
ProfileLeave's Leave2 slow path passes argumentRange to the profiler's FunctionLeave2 hook, but ProfilingGetFunctionLeave3Info does not always write it. The slow path is taken whenever COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_STACK_SNAPSHOT or COR_PRF_ENABLE_FUNCTION_RETVAL is set, while the query fills the range only when COR_PRF_ENABLE_FUNCTION_RETVAL is set; it also returns early, before filling it, on an allocation failure. Only a debug assert checks the result. In those cases the hook received indeterminate values from the stack. Initialize the range so the hook gets an empty range instead.
|
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. |
Contributor
|
Tagging subscribers to this area: @agocke |
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
lateralusX
approved these changes
Oct 15, 2026
Contributor
Author
|
Thank you for the review and the merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ProfileLeave's Leave2 slow path declaresCOR_PRF_FUNCTION_ARGUMENT_RANGE argumentRange;uninitialized, callsProfilingGetFunctionLeave3Info, checks the result only with_ASSERTE(hr == S_OK), and passes&argumentRangeto the profiler'sFunctionLeave2hook.The query does not always write the range. The slow path is taken whenever
COR_PRF_ENABLE_FRAME_INFO,COR_PRF_ENABLE_STACK_SNAPSHOTorCOR_PRF_ENABLE_FUNCTION_RETVALis set, but the query fills the range only whenCOR_PRF_ENABLE_FUNCTION_RETVALis set. It also returnsE_UNEXPECTEDbefore writing anything if its iterator allocation fails. In those cases the hook receives whatever was on the stack. This zero-initializes the range, so the hook gets an empty one.I measured the first case with a
FunctionLeave2hook that enablesCOR_PRF_ENABLE_FRAME_INFOwithoutCOR_PRF_ENABLE_FUNCTION_RETVALand reads only the range's two fields (Release builds; the Leave2 path there is identical tomain's):The
FunctionLeave2docs say return value information requiresCOR_PRF_ENABLE_FUNCTION_RETVAL, so a profiler following them doesn't read the range in that configuration. Still, the hook is handed a pointer to an indeterminate struct. The suspension-Leave discussion on #131985 is also consideringCORPROF_E_DATAINCOMPLETEfor this query, which would add another non-filling path (#131985 (comment)).Testing: the experiment above. On linux-x64 Release, the
src/tests/profilertree passes with this change (together with an unrelated AMD64 profiler fix) onmainas of dca76ff; the four tests that skip themselves unless tiered compilation is disabled were run withDOTNET_TieredCompilation=0. The profiler code involved is unchanged between dca76ff and this branch's base. The allocation-failure path was not exercised. Tailcall2 has no range. Enter2 passesNULLargument info when arguments are off, but its allocated argument buffer is left unfilled if the query's own allocation fails; I haven't changed or tested that here.