Re: [PATCH v2] tracing/uprobe: Add missing PID filter for uretprobe

Tianyi Liu
2024-08-27T06:27:44Z

On 08/27 05:26, Oleg Nesterov wrote:
> __uprobe_register+1
> probe_event_enable+399
> perf_trace_event_init+440
> perf_uprobe_init+152
> perf_uprobe_event_init+74
> perf_try_init_event+71
> perf_event_alloc+1681
> __do_sys_perf_event_open+447
> do_syscall_64+130
> entry_SYSCALL_64_after_hwframe+118
>
> so it seems that bpftrace doesn't use bpf_uprobe_multi_link_attach()
> (called by sys_bpf(BPF_LINK_CREATE) ?) in this case.

I'm using bpftrace v0.21.2 with "uprobe_multi: no", and I got the same
stack as yours.

When I use strace to trace bpftrace, I get:
```
$ strace bpftrace -p 38962 -e 'uretprobe:libc:malloc { printf("time=%llu pid=%d\n", elapsed / 1000000000, pid); }' 2>&1 | grep perf_event_open
perf_event_open({type=0x7 /* PERF_TYPE_??? */, size=0x88 /* PERF_ATTR_SIZE_??? */,config=0x1, sample_period=1,
sample_type=0, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, 38962, -1, -1, PERF_FLAG_FD_CLOEXEC) = 12

$ cat /sys/bus/event_source/devices/uprobe/type
7
```

Here bpftrace is using "uprobe" as the event type, which is registered in
```
static struct pmu perf_uprobe = {
.task_ctx_nr = perf_sw_context,
.event_init = perf_uprobe_event_init,
.add = perf_trace_add,
.del = perf_trace_del,
.start = perf_swevent_start,
.stop = perf_swevent_stop,
.read = perf_swevent_read,
.attr_groups = uprobe_attr_groups,
};
perf_pmu_register(&perf_uprobe, "uprobe", -1);
```

While I use strace for perf, I get:
```
$ strace perf trace -e probe_libc:malloc__return -p 38962 2>&1 |grep perf_event_open
[...]
perf_event_open({type=PERF_TYPE_TRACEPOINT, size=0x88 /* PERF_ATTR_SIZE_??? */, config=1641, sample_period=1,
sample_type=PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_TIME|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD|PERF_SAMPLE_RAW,
read_format=PERF_FORMAT_ID, disabled=1, mmap=1, comm=1, task=1, precise_ip=0 /* arbitrary skid */, sample_id_all=1,
exclude_guest=1, mmap2=1, comm_exec=1, ksymbol=1, bpf_event=1, ...}, 38962, -1, -1, PERF_FLAG_FD_CLOEXEC) = 3
```

The PERF_TYPE_TRACEPOINT is registered in:
```
static struct pmu perf_tracepoint = {
.task_ctx_nr = perf_sw_context,
.event_init = perf_tp_event_init,
.add = perf_trace_add,
.del = perf_trace_del,
.start = perf_swevent_start,
.stop = perf_swevent_stop,
.read = perf_swevent_read,
};
perf_pmu_register(&perf_tracepoint, "tracepoint", PERF_TYPE_TRACEPOINT);
```

So there's a slight difference between the event types being used. I
haven't found the connection between this and the filtering, just WFI.

By the way, I used bpftrace just for convenience in reproducing the issue.
This bug was originally discovered while using cilium/ebpf (a golang ebpf
library), which also uses "uprobe" as the event type [1].

[1] https://github.com/cilium/ebpf/blob/main/link/kprobe.go#L251