Отправка строк в пространство карты BPF и их печать

У меня есть небольшой текстовый файл, который я хотел бы записать здесь в BPF. Вот как выглядит мой код Python для BPF, но я пока не могу ничего распечатать. Я продолжаю получать сообщение «Не удалось загрузить программу: неверный аргумент с кучей ошибок регистра». На данный момент моя строка в основном говорит привет, мир, привет

BPF_ARRAY(lookupTable, char, 512);
int helloworld2(void *ctx)
{
    //print the values in the lookup table
    #pragma clang loop unroll(full)
    for (int i = 0; i < 512; i++) {
        char *key = lookupTable.lookup(&i);
        if (key) {
            bpf_trace_printk("%s\n", key);
        }
    }
    return 0;
}

Вот код Python:

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

lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
file_contents = f.read()
#append file contents to the lookupTable array
b_string1 = file_contents.encode('utf-8')
b_string1 = ctypes.create_string_buffer(b_string1)
lookupTable[0] = b_string1
f.close()

b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="helloworld2")
b.trace_print()

У меня есть ссылка на ошибку в этом pastebin, так как он такой длинный: Ошибка BPF

Одной заметной ошибкой является упоминание об обнаружении бесконечного цикла, что мне нужно проверить.


person maxterthrowaway    schedule 27.07.2021    source источник
comment
Вы проверили, что clang действительно развернул цикл (bpftool prog dump xlated <prog> после загрузки или llvm-objdump -S <objfile>, но у вас не будет объектного файла с bcc)? Я подозреваю, что нет, потому что вы передаете указатель с i на lookupTable.lookup(&i), а это означает, что значение в i может измениться внутри цикла, и вы можете потенциально иметь этот бесконечный цикл. Помощник поиска, конечно, доступен только для чтения, но clang не знает об этом.   -  person Qeole    schedule 28.07.2021
comment
Clang на самом деле не смог развернуть цикл из-за характера отправки указателя на поиск. Решение @Pchaigno с промежуточным значением, кажется, отлично работает, заставляя его действительно работать.   -  person maxterthrowaway    schedule 28.07.2021


Ответы (1)


Проблема в том, что i передается указателем в bpf_map_lookup_elem, поэтому компилятор не может фактически развернуть цикл (с его точки зрения, i может не увеличиваться линейно).

Чтобы исправить это, достаточно использовать промежуточную переменную:

BPF_ARRAY(lookupTable, char, 512);
#define MAX_LENGTH 1
int helloworld2(void *ctx)
{
    //print the values in the lookup table
    #pragma clang loop unroll(full)
    for (int i = 0; i < 1; i++) {
        int k = i;
        char *key = lookupTable.lookup(&k);
        if (key) {
            bpf_trace_printk("%s\n", key);
        }
    }
    return 0;
}
person pchaigno    schedule 28.07.2021
comment
Спасибо за помощь! Кажется, мой цикл исправлен, но, к сожалению, ничего не выводится :( - person maxterthrowaway; 28.07.2021
comment
Вы проверили правильность заполнения карты? Как вы проверяете результат, вы cat /sys/kernel/debug/tracing/trace_pipe? - person Qeole; 28.07.2021
comment
Мне удалось получить вывод, но, похоже, в массиве BPF существует произвольное ограничение размера на символ, которое мне нужно разрешить. - person maxterthrowaway; 29.07.2021