-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
- kprobe/fentry 等类型使用
bpf_get_func_ip - tracepoint 类型,bpf_get_func_ip() 返回的是触发 tracepoint 的函数地址,而不是 tracepoint 本身的地址。
// 使用 bpf_get_stack()
struct {
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
__uint(max_entries, 1024);
} stack_traces SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_open")
int trace_open_stack(struct trace_event_raw_sys_enter *ctx)
{
u64 stack_id = bpf_get_stackid(ctx, &stack_traces, BPF_F_FAST_STACK_CMP);
// 或者直接获取栈帧
u64 stack[10];
int ret = bpf_get_stack(ctx, stack, sizeof(stack), 0);
if (ret > 0) {
// stack[0] 是当前执行的指令地址
bpf_printk("Current IP: 0x%lx\n", stack[0]);
}
return 0;
}
// 使用 task_struct 获取到 寄存器信息,然后通过 bpf_get_func_ip(ctx)
SEC("tracepoint/syscalls/sys_enter_open")
int trace_open_task(struct trace_event_raw_sys_enter *ctx)
{
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
// 从任务结构中读取 pt_regs(如果可用)
// 这种方法较为复杂,需要了解内核内部结构
return 0;
}tracepoint 介绍
tracepoint 是编译时就确定的静态插桩点,不像 kprobe 是动态插桩:
// 内核代码中的 tracepoint 定义示例
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
trace_sys_enter(regs, __NR_open); // 这里触发 tracepoint
// 实际的系统调用逻辑
long ret = do_sys_open(AT_FDCWD, filename, flags, mode);
trace_sys_exit(regs, ret); // 这里触发 tracepoint
return ret;
}Metadata
Metadata
Assignees
Labels
No labels