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

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限制以保障程序安全和执行效率。

具体修复步骤

  1. 修改函数参数传递方式
    将Program p改为指针传递Program *p,避免结构体按值拷贝:

    int matchSet(Program *p, int match[], int action)
    
  2. 调整结构体成员访问语法
    因为现在传递的是指针,所有访问p.set的地方要替换为p->set:

    // 示例修改
    if (p->set[i] == match[0] && p->set[i + 1] == match[1])
    
  3. 修正函数调用的参数
    调用matchSet时传入p的地址:

    matchSet(&p, match, 1);
    
  4. 删除函数内的无效覆盖代码
    函数内部重新定义的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)
    
  5. 修复数组越界问题

    • 内层循环j <=4会访问match[4],但match长度为4(索引0-3),改为j <4
    • 外层循环i <10时,i=9访问p->set[i+1]会越界,改为i <9
  6. 补充默认返回值
    当前函数仅在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:25:28