указатель формата bpf_trace_printk

Как "%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


person libo    schedule 11.03.2020    source источник


Ответы (1)


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


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

person pchaigno    schedule 11.03.2020