XDP中出现“pass by value not supported”错误,如何修复?
问题
我正在编写一个遍历集合进行匹配的函数,本应正常运行,但实际出现了“pass by value not supported”错误。
函数代码如下:
int matchSet(Program p, int match[], int action) { int matchState = 0; int match[4] = {3,4,5,6}; //set as example int p.set[10] = {2,1,3,4,5,6,9,10,11,12}; //set as example (normal p.set) for (int i = 0; i < 10; i++) { if (matchState != 2) { if (p.set[i] == match[0] && p.set[i + 1] == match[1]) { matchState = 0; for (int j = 0; j <= 4; j++) { bpf_printk("test"); if (matchState == 0) { bpf_printk("test3"); if (p.set[i] != match[j]) { bpf_printk("test4"); matchState = 1; break; } } } if (matchState == 0) { bpf_printk("test6"); matchState = 2; } } } } if(matchState == 2) { return action; } }
调用方式如下:
Program p; ..... int set[10] = {2,1,3,4,5,6,9,10,11,12}; p.set = set; int match[4] = {3,4,5,6}; matchSet(p, match, 1);
错误信息:
error: pass by value not supported 0x1aca7c8: i64 = GlobalAddress<i32 (%struct.Program*, i8*, i32)* @matchSet> 0
修复方案
核心原因
该错误出现在BPF程序场景中,BPF验证器禁止按值传递复杂结构体(比如Program类型)——结构体按值传递需要拷贝整个对象,这种操作会被BPF限制以保障程序安全和执行效率。
具体修复步骤
修改函数参数传递方式
将Program p改为指针传递Program *p,避免结构体按值拷贝:int matchSet(Program *p, int match[], int action)调整结构体成员访问语法
因为现在传递的是指针,所有访问p.set的地方要替换为p->set:// 示例修改 if (p->set[i] == match[0] && p->set[i + 1] == match[1])修正函数调用的参数
调用matchSet时传入p的地址:matchSet(&p, match, 1);删除函数内的无效覆盖代码
函数内部重新定义的match[4]和p.set[10]会覆盖传入的参数,属于逻辑错误,直接删除这两行:// 删掉以下两行 // int match[4] = {3,4,5,6}; //set as example // int p.set[10] = {2,1,3,4,5,6,9,10,11,12}; //set as example (normal p.set)修复数组越界问题
- 内层循环
j <=4会访问match[4],但match长度为4(索引0-3),改为j <4 - 外层循环
i <10时,i=9访问p->set[i+1]会越界,改为i <9
- 内层循环
补充默认返回值
当前函数仅在matchState ==2时返回值,其他分支无返回会导致未定义行为,在函数末尾添加默认返回:return 0; // 可根据业务逻辑调整返回值
修复后的完整代码
int matchSet(Program *p, int match[], int action) { int matchState = 0; for (int i = 0; i <9; i++) { if (matchState != 2) { if (p->set[i] == match[0] && p->set[i + 1] == match[1]) { matchState = 0; for (int j = 0; j <4; j++) { bpf_printk("test"); if (matchState == 0) { bpf_printk("test3"); if (p->set[i] != match[j]) { bpf_printk("test4"); matchState = 1; break; } } } if (matchState == 0) { bpf_printk("test6"); matchState = 2; } } } } if(matchState == 2) { return action; } return 0; // 默认返回值 }
调用代码修改为:
Program p; ..... int set[10] = {2,1,3,4,5,6,9,10,11,12}; p.set = set; // 注意:若Program的set成员是数组,需确保此处初始化逻辑合法 int match[4] = {3,4,5,6}; matchSet(&p, match, 1);
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

