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

相关推荐
子玖5 小时前
go实现通过ip解析城市
后端·go
Java不加班5 小时前
Java 后端定时任务实现方案与工程化指南
后端
心在飞扬5 小时前
RAG 进阶检索学习笔记
后端
Moment5 小时前
想要长期陪伴你的助理?先从部署一个 OpenClaw 开始 😍😍😍
前端·后端·github
Das1_5 小时前
【Golang 数据结构】Slice 底层机制
后端·go
得物技术5 小时前
深入剖析Spark UI界面:参数与界面详解|得物技术
大数据·后端·spark
古时的风筝5 小时前
花10 分钟时间,把终端改造成“生产力武器”:Ghostty + Yazi + Lazygit 配置全流程
前端·后端·程序员
Cache技术分享5 小时前
340. Java Stream API - 理解并行流的额外开销
前端·后端
初次攀爬者5 小时前
RocketMQ 消息可靠性保障与堆积处理
后端·消息队列·rocketmq