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

相关推荐
wmze1 小时前
InnoDB存储引擎
后端
lifallen1 小时前
Java BitSet类解析:高效位向量实现
java·开发语言·后端·算法
子恒20053 小时前
警惕GO的重复初始化
开发语言·后端·云原生·golang
daiyunchao3 小时前
如何理解"LLM并不理解用户的需求,只是下一个Token的预测,但他能很好的完成任务,比如写对你想要的代码"
后端·ai编程
Android洋芋3 小时前
SettingsActivity.kt深度解析
后端
onejason3 小时前
如何利用 PHP 爬虫按关键字搜索 Amazon 商品
前端·后端·php
令狐冲不冲3 小时前
常用设计模式介绍
后端
Java水解3 小时前
深度解析MySQL中的Join算法:原理、实现与优化
后端·mysql
一语长情3 小时前
关于Netty的DefaultEventExecutorGroup使用
java·后端·架构
易元3 小时前
设计模式-状态模式
后端·设计模式