You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置struct perf_event_attr标志位触发syscall错误,perf工具正常的问题求助

解决perf_event_open设置exclude_*位时的"operation not supported"错误

我在处理perf事件相关问题时遇到过不少类似的情况,结合你描述的场景(自定义v4.6内核、perf命令行正常但自己的syscall调用报错),大概率是以下几个原因之一,你可以按步骤排查:

1. 未正确设置perf_event_attr.size字段

这是最常见的坑!内核会通过attr.size字段判断你传入的结构体版本,如果没有显式设置这个值,内核会默认使用旧版本的结构体大小,而exclude_kernel、exclude_user、exclude_hv这些位可能不在旧版本结构体的有效范围内,内核会直接判定参数无效,返回EOPNOTSUPP。

解决方法:初始化结构体时必须显式设置:

struct perf_event_attr attr = {0};
attr.size = sizeof(struct perf_event_attr); // 这行绝对不能省略!

2. 头文件与自定义内核版本不匹配

你自己编译了perf工具,但测试代码可能使用了系统默认的linux/perf_event.h头文件,而非自定义v4.6内核对应的头文件。如果头文件版本和内核不一致,struct perf_event_attr的定义可能存在差异(比如字段偏移、位的位置不同),导致内核无法正确识别你设置的exclude_*位。

解决方法:编译测试程序时,指定自定义内核的头文件路径:

gcc -o perf_test perf_test.c -I/path/to/your/custom/kernel/include

替换/path/to/your/custom/kernel/include为你实际的v4.6内核头文件目录(比如/usr/src/linux-4.6/include)。

3. 所选事件类型不支持exclude_*过滤

不是所有perf事件都支持内核/用户空间过滤,比如某些tracepoint事件或特定硬件事件可能不具备这个功能。但你提到perf命令行工具能正常工作,说明至少有部分事件支持该过滤,你可以先复制perf命令行使用的事件类型来测试。

比如perf默认常用的CPU周期事件,你可以在代码里这样设置:

attr.type = PERF_TYPE_HARDWARE;
attr.config = PERF_COUNT_HW_CPU_CYCLES;
attr.exclude_kernel = 1; // 尝试设置该位

4. 查看内核日志获取更详细的错误信息

内核通常会在dmesg中输出更具体的错误原因,你可以执行dmesg | grep perf查找相关日志,比如可能会看到“perf_event_attr size invalid”或者“event X does not support exclude_kernel”这样的提示,能帮你快速定位问题。

5. 对比perf工具的源码实现

既然perf命令行能正常工作,你可以查看perf工具中调用perf_event_open的代码(比如perf_event_open.c文件),看看它是如何初始化perf_event_attr结构体的,对比自己的代码找出差异。perf工具肯定处理了结构体版本兼容和参数校验的问题,参考它的实现能帮你快速修正自己的代码。


内容的提问来源于stack exchange,提问作者user3527764

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:19:26