【问题标题】:Bad address error when comparing Strings within BPF比较 BPF 中的字符串时出现错误的地址错误
【发布时间】:2021-10-09 22:48:13
【问题描述】:

我在这里运行了一个示例程序,以查看子字符串是否与字符串匹配,然后将它们打印出来。到目前为止,由于地址错误,我无法运行该程序。我想知道是否有办法解决这个问题?我附上了整个代码,但我的问题主要与 isSubstring 有关。

#include <uapi/linux/bpf.h>
#define ARRAYSIZE 64

struct data_t {
    char buf[ARRAYSIZE];
};

BPF_ARRAY(lookupTable, struct data_t, ARRAYSIZE);
//char name[20]; 

//find substring in a string
static bool isSubstring(struct data_t stringVal)
{
    char substring[] = "New York";
    int M = sizeof(substring);
    int N = sizeof(stringVal.buf) - 1;
 
    /* A loop to slide pat[] one by one */
    for (int i = 0; i <= N - M; i++) {
        int j;
 
        /* For current index i, check for
 pattern match */
        for (j = 0; j < M; j++)
            if (stringVal.buf[i + j] != substring[j])
                break;
 
        if (j == M)
            return true;
    }
 
    return false;
}

int Test(void *ctx)
{
    #pragma clang loop unroll(full)
    for (int i = 0; i < ARRAYSIZE; i++) {
        int k = i;
        struct data_t *line = lookupTable.lookup(&k);
        if (line) {
            // bpf_trace_printk("%s\n", key->buf);
            if (isSubstring(*line)) {
                bpf_trace_printk("%s\n", line->buf);
            }

        }
    }
    return 0;
}

我的python代码在这里:

import ctypes
from bcc import BPF


b = BPF(src_file="hello.c")

lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
    string = contents[i].encode('utf-8')
    print(len(string))
    lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))

f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="Test")
b.trace_print()

编辑:忘记添加错误:真的很长,可以在这里找到:https://pastebin.com/a7E9L230

我认为错误中最有趣的部分在它提到的底部附近:

8193跳的顺序太复杂了。

再往下一点提到:错误地址。

【问题讨论】:

  • 你能把所有的错误都包括进去吗?
  • 抱歉刚刚添加了错误。完全忘记了我的想法
  • 您是否尝试过bpf_trace_printk 调用来打印传入的字符串?我猜跳跃的次数与你的双循环有多长有关。
  • 是的,打印出来就好了,但是添加额外的功能似乎会破坏功能似乎会破坏应用程序。
  • 验证器检查程序中的所有分支。每次看到跳转指令时,它都会将新分支推送到其分支堆栈进行检查。正如验证者告诉你的那样,这个堆栈有一个你正在达到的限制(BPF_COMPLEXITY_LIMIT_JMP_SEQ,目前是 8192)。 “Bad Address”只是内核的 errno 值的转换,在这种情况下设置为-EFAULT。不知道如何修复它,尝试 1)使用较小的字符串,或 2)在 5.3+ 内核(支持有界循环)上:不使用 clang 展开循环(我不知道它是否有帮助)。跨度>

标签: bpf ebpf bcc-bpf


【解决方案1】:

验证器检查程序中的所有分支。每次看到跳转指令时,它都会将新分支推送到其“要检查的分支堆栈”。正如验证者告诉你的那样,这个堆栈有一个你正在达到的限制(BPF_COMPLEXITY_LIMIT_JMP_SEQ,目前是 8192)。 “Bad Address”只是内核的errno 值的转换,在这种情况下设置为-EFAULT

不知道怎么解决,你可以试试:

  1. 使用较小的字符串,或
  2. 在 5.3+ 内核上(支持有界循环):不使用 clang 展开循环(我不知道它是否有帮助)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 2014-11-28
    相关资源
    最近更新 更多