Fix --profile function timing stack leak on nextfile inside a function - #581
Merged
bertysentry merged 1 commit intoAug 18, 2026
Conversation
Under --profile, executeNextfile unwound the runtime call frames without touching activeProfilingFunctions, so every nextfile executed from inside a user-defined function permanently leaked a deque entry (unbounded growth on long profiled runs) and the abandoned calls were missing from the function timing report, or accounted at program exit with wildly wrong durations. resetCallState() now records exits for all active profiling functions before unwinding, and executeNextfile delegates to it instead of its inline two-line unwind. This also fixes a second leak on the same path: elementArgumentReferences was never cleared on nextfile. The exception abort paths, which already went through resetCallState(), settle the profiling stack the same way. `next` inside a user-defined function, also named by the issue, is currently rejected at compile time (gawk accepts it); that compat gap is tracked separately in #580. Fixes #557 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bertysentry
deleted the
557-profile-function-timing-stack-leaks-on-nextnextfile-inside-a-function
branch
August 18, 2026 18:56
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.
Fixes #557
Problem
Under
--profile,executeNextfileunwound the runtime call frames (popAllFrames+clearOperandStack) without touchingactiveProfilingFunctions. Everynextfileexecuted from inside a user-defined function therefore:Fix
resetCallState()now records exits for all active profiling functions (via the existingrecordAllFunctionExits) before unwinding, mirroring whatEXIT_*does, so the durations end at the point the calls are abandoned.executeNextfiledelegates toresetCallState()instead of its inline two-line unwind. This also fixes a second leak on the same path:elementArgumentReferenceswas never cleared onnextfile.resetCallState(), now settle the profiling stack the same way, so a reused AVM cannot carry stale entries into a later run.Notes
nextinside a function, but Jawk currently rejects that at compile time (cannot next; not within any input rules) while gawk accepts it — that compat gap is tracked separately innextinside a user-defined function is rejected at compile time #580, and its future implementation will inherit this fix by unwinding throughresetCallState().profileOptionRecordsFunctionsUnwoundByNextfiledrives--profilewith a nestedouter() -> inner() -> nextfilechain across three input files and asserts each function is reported with exactly 3 executions. It fails on unfixed code (inner/outermissing from the report) and passes with the fix.Unreleasedin behavior-changes.md.mvn verifypasses (checkstyle, PMD, SpotBugs clean); the failsafe compat-suite failures are the known pre-existing ones (@loadetc.), unrelated to this change.🤖 Generated with Claude Code