указатель формата bpf_trace_printk - PullRequest
5 голосов
/ 11 марта 2020

Как "%p" реализован в bpf_trace_printk? С printf.

#include <uapi/linux/ptrace.h>

int print_args(struct pt_regs *ctx) {
    void *ptr = (void*)PT_REGS_PARM1(ctx);
    bpf_trace_printk("args: %lx %p %ld\n", ptr, ptr, ptr);
    return 0;
}

это выглядит совсем по-другому. Я использую эту программу eBPF для отслеживания аргументов одной функции. Тип параметра - указатель на некоторую структуру.

Один вывод: args: 7ffde047d6c4 00000000ec7e9023 140728366257860

Мы можем заметить, что вывод "%p" очень странный. Если мы используем стандартную C программу для проверки вывода:

#include <stdio.h>

int main() {
    void *ptr = (void*)0x7ffde047d6c4;
    printf("args: %lx %p %ld\n", ptr, ptr, ptr);
    return 0;
}

Мы получим: args: 7ffde047d6c4 0x7ffde047d6c4 140728366257860

1 Ответ

2 голосов
/ 11 марта 2020

TL; DR. Значение, которое вы видите, представляет собой га sh фактического адреса, вычисленного как ptr_to_id(). Адрес хешируется, чтобы избежать утечек указателя, при этом все еще имея возможность использовать это значение в качестве уникального идентификатора.


Пояснения. Реализацию помощника bpf_trace_printk можно найти в kernel/trace/bpf_trace.c в исходниках ядра. Большая часть кода предназначена для ограничения используемых вами спецификаторов перед вызовом __trace_printk(). Вы можете проследить след функций до vsnprintf(), который для %p вызывает pointer(), чье поведение по умолчанию - ha sh адрес, которого следует избегать утечка указателя .

...