WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

support: 如何获取 tp/kprobe 函数本身的 IP #14

@Ghostbaby

Description

@Ghostbaby
  1. kprobe/fentry 等类型使用 bpf_get_func_ip
  2. 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions