Skip to content

Add -N/--max-depth-outer to keep the outermost frames - #163

Merged
adsr merged 1 commit into
masterfrom
max-outer-frames
Sep 7, 2026
Merged

adsr merged 1 commit into
masterfrom
max-outer-frames

Conversation

@adsr

@adsr adsr commented Sep 7, 2026

Copy link
Copy Markdown
Owner

#160 with some merge conflicts fixed, and one perf optimization. (With -N, we save the stack frame pointers when measuring depth, so we don't have to remote copy them again.)

-n keeps the innermost frames, which is the wrong end for attributing a sample
to a phase of the program. With -n 30 on a 100-deep recursion you get the leaf
detail and lose the ability to say whether the sample is under parseFile or
analyzeFile -- which, on a long multi-stage job, is usually the question worth
answering. -N keeps the outermost frames instead, and the two compose: -n 2
-N 2 keeps both ends and elides the middle.

Keeping the outermost frames means knowing the depth before emitting anything,
so trace_stack gains a counting pre-pass. It copies only the
prev_execute_data pointer rather than each frame, and is skipped entirely
unless -N is given, so nothing changes for existing invocations.

The emitted sequence always begins at depth 0: when the innermost frames are
themselves elided, the marker takes depth 0. stackcollapse-phpspy.pl flushes
its accumulated stack on depth 0, so without that every trace in a file would
silently merge into one. The marker's function token is whitespace-free
(`<elided:19>`) because both that script and top.c split frame lines on
spaces, and `#`-prefixed lines were not an option for the same reason.

Stack walks are bounded by PHPSPY_MAX_STACK_WALK, since a torn read of
prev_execute_data could otherwise loop forever -- a latent issue in the
existing single-pass walk too.

-N composes usefully with -b: capping the stack is the cheapest way to keep
deep traces inside the per-trace output budget.

Co-authored-by: Adam Saponara <as@php.net>
@adsr
adsr merged commit c29a9fb into master Sep 7, 2026
2 checks passed
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.

2 participants