Repository navigation
Conversation
On a perf event with PERF_SAMPLE_CALLCHAIN, bpf_get_stack() copies the precomputed callchain, and the kernel part starts with the PERF_CONTEXT_KERNEL marker. try_get_stack() treated the marker as the leaf frame: - kallsyms resolved PERF_CONTEXT_KERNEL (0xffffffffffffff80) to the last symbol of the last loaded module, so every kernel stack got a fake leaf such as cleanup_module@[tun] or init_module@[nft_reject_inet]; - the real leaf was decremented as if it were a return address. Drop a leading marker in try_get_stack() before the return address adjustment. The same helper collects frame pointer user stacks, where the callchain would start with PERF_CONTEXT_USER, so the check is not specific to kernel stacks. Skip marker values in the sample consumer as a second line of defense.
✅ All contributors are covered under a CLA with YandexSee CONTRIBUTING.md for more info about Yandex Contributor License Agreement. The following contributors were found: (Only the first commit for a unique contributor is listed) |
This was referenced Nov 13, 2026
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.
Problem
Every kernel stack recorded by Perforator ends in a fake leaf frame: the last symbol of the last loaded
kernel module, e.g.
cleanup_module@[tun],xt_nat_init@[xt_nat]orinit_module@[nft_reject_inet].Which module it is depends on the host.
The agent opens perf events with
PERF_SAMPLE_CALLCHAIN, sobpf_get_stack()copies the precomputedcallchain. Its kernel part starts with the
PERF_CONTEXT_KERNELmarker ((u64)-128), not with the leaf.try_get_stack()kept the marker as frame 0:0xffffffffffffff80to the last symbol in/proc/kallsyms, a module symbol;Fix
try_get_stack()drops a leadingPERF_CONTEXT_*marker before the return address adjustment.The helper also collects frame pointer user stacks, whose callchain would start with
PERF_CONTEXT_USER, so the check is generic.Testing
TestKernelStackSkipsPerfContextMarkers(agent/collector/pkg/profiler): a kernel stack withmarkers resolves to the real frames only. Without the Go check it fails with
cleanup_module@[tun]frames.perforator record -a -F 999 -d 15s, before and after the change.Repro
Full source: repro-a.c.
Before: every
getrandomstack ends ininit_module@[nft_reject_inet]; it is the leaf of 99.9% of thesamples, so it shows up as the hottest function. After: the real leaves are
chacha_permute,copy_to_iterandchacha_block_generic.