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

相关推荐
程序员cxuan2 小时前
Loop 还没玩明白,Graph Engineering 又火了。
人工智能·后端·程序员
uzong2 小时前
把一面面试总结做成一个 Skill:重复的事,就别每次都重写
后端·面试
程序员海军3 小时前
一个 AI 应用开发程序员的一天,都在屏幕前忙些什么?
前端·后端·程序员
不能放弃治疗3 小时前
MCP
后端
江湖十年4 小时前
Go 语言中 YAML to JSON 踩坑笔记
后端·go·json
你驴我5 小时前
WhatsApp 消息撤回与编辑的幂等性设计实践
java·服务器·前端·后端·python
一缕清烟在人间5 小时前
HarmonyOS开发实战:小分享-TextEditPage文字编辑器——Header+TextArea+工具栏
后端·华为·harmonyos·鸿蒙
人间凡尔赛5 小时前
K8s 十年之变:从 Cloud Native 到 AI Native,2026 年后端架构的范式革命
后端·云原生·架构
程序员cxuan5 小时前
Opus 5 深夜炸场,价格还挺香。。。
人工智能·后端·程序员
北冥you鱼5 小时前
Go 语言新手扫盲:指针 * 和 & 使用场景详解
开发语言·后端·golang