中是如何"%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;
}
Run Code Online (Sandbox Code Playgroud)
我使用这个 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;
}
Run Code Online (Sandbox Code Playgroud)
我们将获得: args: 7ffde047d6c4 0x7ffde047d6c4 140728366257860
TL;博士。您看到的值是实际地址的哈希值,由 计算得出ptr_to_id()。该地址经过哈希处理以避免指针泄漏,同时仍然能够使用该值作为唯一标识符。
解释。帮助程序的实现可以在内核源代码中bpf_trace_printk找到。kernel/trace/bpf_trace.c大多数代码都是为了在调用之前限制您可以使用的说明符__trace_printk()。vsnprintf()您可以追踪for调用的函数,其默认行为是对地址进行哈希处理以避免指针%p泄漏。pointer()