【问题标题】:Can't access correctly to tracepoint context struct fields无法正确访问跟踪点上下文结构字段
【发布时间】:2020-01-03 12:15:02
【问题描述】:

目标:仅当使用 O_RDONLY 标志调用 openat 时才写入 trace_pipe。我已经构建了结构,查看此处包含的格式 /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format

问题 我认为我没有访问 flags 字段,因为看起来第二个 if 语句总是错误的。 问题:我是否正确访问了标志字段?有没有办法打印标志变量内容?

struct syscalls_enter_openat_args {
    __u64 pad;
    int __syscall_nr;
    const char * filename;
    int flags;
    unsigned short modep;
};
SEC("tracepoint/syscalls/sys_enter_openat")
int bpf_sys(struct syscalls_enter_openat_args *ctx)
{
    char fmt[] = "llo\n";
    int flags = ctx->flags;

    if (flags){
        if (flags == O_RDONLY)
            bpf_trace_printk(fmt, sizeof(fmt)); 
    }
    return 0;
}
char _license[] SEC("license") = "GPL";

【问题讨论】:

  • 不确定这是您问题的原因,但通常您使用flags & O_RDONLY 而非== 检查标志,以防flags 还包含其他标志。你试过了吗?
  • 该死,谢谢@Qeole。

标签: c bpf ebpf tracepoint


【解决方案1】:

所以你提到以下检查总是评估为假:

if (flags == O_RDONLY)

这可能是因为通过变量flags 传递给openat() 的标志不仅仅是O_RDONLY。来自openat() 手册页:

参数flags 必须包含以下访问模式之一O_RDONLYO_WRONLYO_RDWR。这些请求分别以只读、只写或读/写方式打开文件。

此外,零个或多个文件创建标志和文件状态标志可以按位标志中。 文件创建标志O_CLOEXECO_CREATO_DIRECTORYO_EXCLO_NOCTTYO_NOFOLLOWO_TMPFILEO_TRUNC。文件状态标志是下面列出的所有剩余标志。这两组标志的区别在于文件创建标志影响打开操作本身的语义,而文件状态标志影响后续I/O操作的语义。 文件状态标志可以被检索和(在某些情况下)修改;详情请见fcntl(2)

因此,与其检查您的flags 是否等于O_RDONLY,不如检查它们是否包含标志,方法是像这个:

if (flags & O_RDONLY)

至于打印flags 的值,用这样的东西可能是可行的(未测试):

        char fmt[] = "flags: %x\n";
        int flags = ctx->flags;

        if (flags & O_RDONLY)
                bpf_trace_printk(fmt, sizeof(fmt), flags); 

【讨论】:

  • 谢谢,无论如何我有疑问,如果我 strace 程序调用 openat 仅包含 O_RDONLY ,则不使用其他标志。所以我希望 flags=O_RDONLY
  • 是的,也许您只有O_RDONLY(在这种情况下,使用== 检查应该确实有效),这不是您的问题的原因。你的 BPF 程序是否成功加载(bpftool prog)?附加成功(试试bpftool perf)?当openat() 运行时,你能看到来自bpf_trace_printk() 的消息吗?你能从你的 BPF 程序中打印出flags 的值吗?
猜你喜欢
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多