【发布时间】:2018-11-19 11:43:56
【问题描述】:
我想跟踪特定 PID 的函数并收集一些统计信息(总调用次数、总时间等),但我并不完全清楚如何使用 funcname+my_struct 对创建 BPF_HASH。
有什么方法可以获取BPF程序中被调用函数的名字吗?
我想我应该使用“PT_REGS_IP(ctx)”读取 IP 寄存器,但我不完全理解如何将值转换为人类可读的字符串。
目前 BPF 程序如下所示:
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
struct data_t {
u32 pid;
u64 delta;
u64 start;
} __attribute__((packed));
BPF_HASH(faddr, u64, struct data_t);
BPF_PERF_OUTPUT(events);
int do_entry(struct pt_regs *ctx) {
struct data_t *data;
data->start = bpf_ktime_get_ns();
u64 ip = PT_REGS_IP(ctx);
faddr.update(&ip, data);
return 0;
}
int do_return(struct pt_regs *ctx) {
struct data_t *data;
u64 ip = PT_REGS_IP(ctx);
data = faddr.lookup(&ip);
if (data->start == 0)
return 0; // missed start
data->delta = bpf_ktime_get_ns() - data->start;
data->pid = bpf_get_current_pid_tgid();
events.perf_submit(ctx, &data, sizeof(data));
faddr.delete(&ip);
return 0;
}
但在启动时我得到了:
error: <unknown>:0:0: in function do_entry i32 (%struct.pt_regs*): A call to built-in function 'abort' is not supported.
【问题讨论】:
-
能否请您提供用于编译、加载和附加程序的命令?
-
抱歉不完整。完整的代码示例可以在我之前的question 中找到,其中有跟踪的 C 程序示例和主 Go 程序示例。 C程序应该用调试符号编译(gcc -g),go程序用默认编译(go build)
-
最好在每个问题中提供一个最小的、可重现的示例程序,即使这意味着问题之间有一些重复的内容。用户空间代码是运行 BPF 程序所必需的,想要重现的人可能没有阅读您之前的问题。
-
好的,接下来的问题会做。