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 在收集数据时的开销,因为它需要收集和存储更长的调用栈信息。

相关推荐
葫芦和十三7 小时前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗11 小时前
单 Agent 实现模式
后端
IT_陈寒13 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
fliter14 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
fliter15 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪15 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter15 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶15 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿16 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝16 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员