The branch main has been updated by mhorne:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1db0c9fa7a32255c452c2536d657e63b55e30e03

commit 1db0c9fa7a32255c452c2536d657e63b55e30e03
Author:     Nick Banks <[email protected]>
AuthorDate: 2026-09-02 14:28:54 +0000
Commit:     Mitchell Horne <[email protected]>
CommitDate: 2026-09-02 14:29:08 +0000

    hwpmc(4): stop overwalking past _start on amd64 user callchains
    
    pmc_save_user_callchain() emits the pc it just loaded before checking
    whether fp is the ABI's zero frame-chain terminator. At the bottom of
    a well-formed chain under _start, fp comes back 0 as expected, but the
    paired pc is stale rtld data left on the stack -- a legal userspace VA
    that still passes PMC_IN_USERSPACE(), so it gets emitted as a bogus
    extra frame. This shows up in flame graphs as a spurious hex-valued
    root frame below _start.
    
    Check fp == 0 alongside the existing checks before emitting, matching
    how arm/arm64/powerpc already load the next fp before their check.
    
    Measured via 1kHz hwpmc sampling on an OCA: stacks with any unresolved
    hex frame drop from 23.9% to 1.3%, and stacks with hex at the root drop
    from 5.5% to 0.3%.
    
    Reviewed by:    mhorne, Ali Mashtizadeh <[email protected]>, gallatin
    MFC after:      3 days
    Sponsored by:   Netflix
    Differential Revision:  https://reviews.freebsd.org/D59229
---
 sys/dev/hwpmc/hwpmc_x86.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c
index 2903c25ef5c9..c32242a2bbb9 100644
--- a/sys/dev/hwpmc/hwpmc_x86.c
+++ b/sys/dev/hwpmc/hwpmc_x86.c
@@ -107,7 +107,8 @@ pmc_save_user_callchain(uintptr_t *cc, int nframes, struct 
trapframe *tf)
                return (n);
 
        for (; n < nframes;) {
-               if (pc == 0 || !PMC_IN_USERSPACE(pc))
+               /* fp == 0 is the ABI frame-chain sentinel below _start. */
+               if (pc == 0 || !PMC_IN_USERSPACE(pc) || fp == 0)
                        break;
 
                *cc++ = pc; n++;

Reply via email to