trace - 在 eBPF 中取被调用函数的名称
问题描述
我想跟踪特定 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.
解决方案
你的do_entry
函数有错误。您正在尝试取消引用空指针:
struct data_t *data;
data->start = bpf_ktime_get_ns();
以下应该更好地工作:
int do_entry(struct pt_regs *ctx) {
struct data_t data = {}; // initializes data with zeros.
data.start = bpf_ktime_get_ns();
u64 ip = PT_REGS_IP(ctx);
faddr.update(&ip, &data);
return 0;
}
我不明白为什么错误消息提到abort
了。我会四处打听。
如何将内存地址转换为函数名称取决于您使用的用户空间库。如果您使用密件抄送,ksym
您可以使用一种方法。我不知道 gobpf 中是否有等价物。
您至少有一个其他错误,在do_return
:
data = faddr.lookup(&ip);
if (data->start == 0)
return 0; // missed start
data
在取消引用之前,您需要检查is not null 。否则,验证者将拒绝您的程序。
data = faddr.lookup(&ip);
if (!data || data->start == 0)
return 0; // missed start
推荐阅读
- reactjs - 仅本地主机上的 Firebase 托管保留 URL“/__/firebase/init.js”中缺少应用配置 appId
- reactjs - React router will keep its state data even after a browser refresh
- python - How to align text in a tkinter Listbox
- fluentd - 启用 Fluentd 日志轮换
- swift - 如何使用 RXSwift 和 MVVM 使条件逻辑和重置可观察
- javascript - Filter a JSON array based on a property
- mongodb - In Spring MongoDB update, MonogDB doc replaced/lost fields, becomes empty, oplog "o" for this update has no $set, $unset, has only objectId as in "o2"
- java - 没有名为 bookPU 的 EntityManager 的持久性提供程序
- c++ - Why am I getting a crash after calling my constructor? I'm trying to push back a shared_ptr to a vector
- c++ - 需要帮助来修复我的代码以执行特定逻辑