I am trying function count for given executable and pattern. trying to explore latest introduced API bpf_program__attach_uprobe_multi, couldn't find example for the same. below code failing with invalid argument. added prints in libbpf code, looks like path, pattern, variable taken properly ibbpf: func pattern op_* path /data/expr/operations from libbps cnt 2 libbpf: offsets 4521 4538
libbpf: prog 'test_uprobe': failed to attach multi-uprobe: Invalid argument
Not sure what am i missing here.
Below is hardcode in kernel bpf code.
`// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
`int main(int argc, char **argv)
{
size_t offset1;
size_t offset2;
int err, i;
char filename[256];
pid_t pid;
struct bpf_object *obj = NULL;
struct bpf_program *prog[2];
static struct bpf_link *bpflinks[2];
static struct bpf_link *ubpflinks[2];
if (argc < 2) {
printf("Error return \n");
return 0;
}
pid = strtoul(argv[1], NULL, 10);
snprintf(filename, 256, "/proc/%d/exe", pid);
offset1 = get_elf_func_offset("/data/expr/operations", "op_add");
offset2 = get_elf_func_offset("/data/expr/operations", "op_sub");
snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]);
obj = bpf_object__open_file(filename, NULL);
if (libbpf_get_error(obj)) {
fprintf(stderr, "ERROR: opening BPF object file failed\n");
obj = NULL;
goto cleanup;
}
/* load BPF program */
if (bpf_object__load(obj)) {
fprintf(stderr, "ERROR: loading BPF object file failed\n");
goto cleanup;
}
prog[0] = bpf_object__find_program_by_name(obj, "handle_uprobe_ref_ctr");
// prog[1] = bpf_object__find_program_by_name(obj, "handle_uretprobe_ref_ctr");
ubpflinks[0] =
bpf_program__attach_uprobe(prog[0], false /* not uretprobe */,
pid, "/data/expr/operations" , offset1);
if (!ubpflinks[0])
printf("failed at link0\n");
ubpflinks[1] =
bpf_program__attach_uprobe(prog[0], false /* not uretprobe */,
pid, "/data/expr/operations" , offset2);
if (!ubpflinks[1])
printf("failed at link1\n");
// bpflinks[0] = bpf_program__attach(prog[0]); // do we need to attach already probes attached
getchar();
cleanup:
bpf_link__destroy(ubpflinks[0]);
bpf_link__destroy(ubpflinks[1]);
return -err;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";
SEC("uprobe")
int handle_uprobe_ref_ctr(struct pt_regs *ctx)
{
const char fmt_str[] = "function fp %lld ip %lld\n";
bpf_trace_printk(fmt_str, sizeof(fmt_str), (void *)PT_REGS_FP(ctx));
return 0;
}
SEC("uretprobe")
int handle_uretprobe_ref_ctr(struct pt_regs *ctx)
{
bpf_printk("handle_uretprobe_ref_ctr \n");
return 0;
}
`
The uprobe multi-attach support has been merged in bpf-next, but hasn't been released yet. I'd expect it to make it into Linux v6.6.
For older kernels, you will have to rely on bpf_program__attach_uprobe
:
LIBBPF_API struct bpf_link * bpf_program__attach_uprobe (const struct bpf_program *prog, bool retprobe, pid_t pid, const char *binary_path, size_t func_offset)
Note the bpf_program__attach_uprobe_multi
function from libbpf also hasn't been released yet. Libbpf v1.2.2 only has bpf_program__attach_uprobe
.