stack_traces 创建失败

环境

map 定义:

scss 复制代码
#define PERF_MAX_STACK_DEPTH 128
struct
{
    __uint(type, BPF_MAP_TYPE_STACK_TRACE);
    __uint(key_size, sizeof(u32));
    __uint(value_size, PERF_MAX_STACK_DEPTH * sizeof(u64));
    __uint(max_entries, 10000);
} stack_traces SEC(".maps");

启动报错:

bash 复制代码
2025-06-11T14:29:58.761+0800    FATAL   memleak/main.go:69      加载 BPF 程序失败       {"error": "load and attach BPF programs failed: load collection error: map stack_traces: map create: invalid argument"}
main.main
        /workload/BeePF/example/memleak/main.go:69
runtime.main
        /workload/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.8.linux-amd64/src/runtime/proc.go:272
make: *** [Makefile:33: run] Error 1

排查

命令:retsnoop -e '*sys_bpf' -TAS -C args.fmt-mode=verbose 日志:

ini 复制代码
14:29:58.761884 -> 14:29:58.761888 TID/PID 60628/60626 (memleak/memleak):
​
FUNCTION CALLS    RESULT     DURATION
---------------   ---------  --------
→ __x64_sys_bpf                      
                  › __unused = &{
                      .r15 = 0xffffffff,
                      .r14 = 0xc0000061c0,
                      .r13 = 0xc0016ddf80,
                      .r12 = 0xc0016d40f0,
                      .bp = 0xc0016d3f70,
                      .r11 = 534,
                      .ax = 0xffffffffffffffda,
                      .cx = 0x4808ee,
                      .dx = 80,
                      .si = 0xc0016d4360,
                      .orig_ax = 321,
                      .ip = 0x4808ee,
                      {
                          .cs = 51,
                          .csx = 51,
                          .fred_cs = {
                              .cs = 51
                          }
                      },
                      .flags = 534,
                      .sp = 0xc0016d3ee0,
                      {
                          .ss = 43,
                          .ssx = 43,
                          .fred_ss = {
                              .ss = 43
                          }
                      }
                  }
    ↔ __sys_bpf   [-EINVAL]   1.508us
                  › cmd = 0
                  › uattr = {
                      {
                          .kernel = 0xc0016d4360,
                          .user = 0xc0016d4360
                      }
                  }
                  › size = 80
← __x64_sys_bpf   [-EINVAL]   3.270us

调用详情分析:

  1. 系统调用参数
ini 复制代码
cmd = 0          # BPF_MAP_CREATE (创建 BPF map)
uattr = 0xc0016d4360  # 指向用户空间的 bpf_attr 结构
size = 80        # bpf_attr 结构的大小
  1. 返回结果 错误码: [-EINVAL] (无效参数)

问题分析 这个错误表明在尝试创建 BPF map 时,传递给内核的参数无效。结合 memleak.c 文件,可能的原因包括:

  • Map 大小限制: 某个 map 的 max_entries 超出了系统限制

根因

c 复制代码
#define PERF_MAX_STACK_DEPTH 128
...
__uint(value_size, PERF_MAX_STACK_DEPTH * sizeof(u64));
...

Linux 内核参数 PERF_MAX_STACK_DEPTH 的默认值是 127

这个参数定义了 perf 工具在收集调用栈(call stack)时,能够记录的最大深度。也就是说,如果一个函数调用链的深度超过 127 层,perf 将只会记录前 127 层。

可以通过 /proc/sys/kernel/perf_event_max_stack 这个 sysctl 接口来查看和修改这个值。例如:

  • 查看当前值:

    bash 复制代码
    cat /proc/sys/kernel/perf_event_max_stack
  • 修改值 (例如,改为 256):

    bash 复制代码
    echo 256 > /proc/sys/kernel/perf_event_max_stack

请注意,增加 PERF_MAX_STACK_DEPTH 的值可能会增加 perf 在收集数据时的开销,因为它需要收集和存储更长的调用栈信息。

相关推荐
Python私教35 分钟前
用 FastAPI + Pydantic 打造“可验证、可热载、可覆盖”的配置中心
后端
Python私教44 分钟前
FastAPI “零手工”路由:自动扫描模块、自动注册路由的工程级实践
后端
用户21411832636022 小时前
Claude Skills 实战指南:3 分钟搞定 PPT、海报与 Logo,AI 办公效率翻倍!
后端
想搞艺术的程序员2 小时前
Go Error 全方位解析:原理、实践、扩展与封装
开发语言·后端·golang
程序定小飞4 小时前
基于springboot的web的音乐网站开发与设计
java·前端·数据库·vue.js·spring boot·后端·spring
舒一笑4 小时前
从手写周报到智能生成:PandaCoder如何让你的工作汇报效率提升10倍
后端·程序员·intellij idea
无名之辈J4 小时前
支付常犯错误
后端
申阳4 小时前
Day 6:04. 基于Nuxt开发博客项目-LOGO生成以及ICON图标引入
前端·后端·程序员
硅胶人4 小时前
[prowlarr][radarr][sonarr][qBitorrent]套件打造家庭影音中心
后端