11e8611bbSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0 21e8611bbSAndrii Nakryiko #include <test_progs.h> 3f3c926a4SAndrii Nakryiko #include "test_attach_probe.skel.h" 41e8611bbSAndrii Nakryiko 54bd11e08SAndrii Nakryiko /* this is how USDT semaphore is actually defined, except volatile modifier */ 64bd11e08SAndrii Nakryiko volatile unsigned short uprobe_ref_ctr __attribute__((unused)) __attribute((section(".probes"))); 74bd11e08SAndrii Nakryiko 8ff943683SAndrii Nakryiko /* uprobe attach point */ 9ff943683SAndrii Nakryiko static void trigger_func(void) 10ff943683SAndrii Nakryiko { 11ff943683SAndrii Nakryiko asm volatile (""); 129e7240fbSYucong Sun } 139e7240fbSYucong Sun 14ba7499bcSAlan Maguire /* attach point for byname uprobe */ 15ba7499bcSAlan Maguire static void trigger_func2(void) 16ba7499bcSAlan Maguire { 17ba7499bcSAlan Maguire asm volatile (""); 18ba7499bcSAlan Maguire } 19ba7499bcSAlan Maguire 201e8611bbSAndrii Nakryiko void test_attach_probe(void) 211e8611bbSAndrii Nakryiko { 224bd11e08SAndrii Nakryiko DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); 23f3c926a4SAndrii Nakryiko struct bpf_link *kprobe_link, *kretprobe_link; 24f3c926a4SAndrii Nakryiko struct bpf_link *uprobe_link, *uretprobe_link; 25f3c926a4SAndrii Nakryiko struct test_attach_probe* skel; 26ff943683SAndrii Nakryiko ssize_t uprobe_offset, ref_ctr_offset; 27ba7499bcSAlan Maguire struct bpf_link *uprobe_err_link; 28d3b0e3b0SAndrii Nakryiko bool legacy; 29ba7499bcSAlan Maguire char *mem; 30d3b0e3b0SAndrii Nakryiko 31d3b0e3b0SAndrii Nakryiko /* Check if new-style kprobe/uprobe API is supported. 32d3b0e3b0SAndrii Nakryiko * Kernels that support new FD-based kprobe and uprobe BPF attachment 33d3b0e3b0SAndrii Nakryiko * through perf_event_open() syscall expose 34d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/kprobe/type and 35d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/uprobe/type files, respectively. They 36d3b0e3b0SAndrii Nakryiko * contain magic numbers that are passed as "type" field of 37d3b0e3b0SAndrii Nakryiko * perf_event_attr. Lack of such file in the system indicates legacy 38d3b0e3b0SAndrii Nakryiko * kernel with old-style kprobe/uprobe attach interface through 39d3b0e3b0SAndrii Nakryiko * creating per-probe event through tracefs. For such cases 40d3b0e3b0SAndrii Nakryiko * ref_ctr_offset feature is not supported, so we don't test it. 41d3b0e3b0SAndrii Nakryiko */ 42d3b0e3b0SAndrii Nakryiko legacy = access("/sys/bus/event_source/devices/kprobe/type", F_OK) != 0; 431e8611bbSAndrii Nakryiko 44ff943683SAndrii Nakryiko uprobe_offset = get_uprobe_offset(&trigger_func); 45ff943683SAndrii Nakryiko if (!ASSERT_GE(uprobe_offset, 0, "uprobe_offset")) 461e8611bbSAndrii Nakryiko return; 471e8611bbSAndrii Nakryiko 484bd11e08SAndrii Nakryiko ref_ctr_offset = get_rel_offset((uintptr_t)&uprobe_ref_ctr); 494bd11e08SAndrii Nakryiko if (!ASSERT_GE(ref_ctr_offset, 0, "ref_ctr_offset")) 504bd11e08SAndrii Nakryiko return; 514bd11e08SAndrii Nakryiko 525dc7a8b2SAndrii Nakryiko skel = test_attach_probe__open_and_load(); 53ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel, "skel_open")) 541e8611bbSAndrii Nakryiko return; 55ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel->bss, "check_bss")) 56928ca75eSAndrii Nakryiko goto cleanup; 57928ca75eSAndrii Nakryiko 58*32c03c49SAndrii Nakryiko /* manual-attach kprobe/kretprobe */ 59f3c926a4SAndrii Nakryiko kprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kprobe, 601e8611bbSAndrii Nakryiko false /* retprobe */, 611cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 62bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe")) 631e8611bbSAndrii Nakryiko goto cleanup; 64f3c926a4SAndrii Nakryiko skel->links.handle_kprobe = kprobe_link; 65f3c926a4SAndrii Nakryiko 66f3c926a4SAndrii Nakryiko kretprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kretprobe, 671e8611bbSAndrii Nakryiko true /* retprobe */, 681cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 69bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe")) 701e8611bbSAndrii Nakryiko goto cleanup; 71f3c926a4SAndrii Nakryiko skel->links.handle_kretprobe = kretprobe_link; 72f3c926a4SAndrii Nakryiko 73*32c03c49SAndrii Nakryiko /* auto-attachable kprobe and kretprobe */ 74*32c03c49SAndrii Nakryiko skel->links.handle_kprobe_auto = bpf_program__attach(skel->progs.handle_kprobe_auto); 75*32c03c49SAndrii Nakryiko ASSERT_OK_PTR(skel->links.handle_kprobe_auto, "attach_kprobe_auto"); 76*32c03c49SAndrii Nakryiko 77*32c03c49SAndrii Nakryiko skel->links.handle_kretprobe_auto = bpf_program__attach(skel->progs.handle_kretprobe_auto); 78*32c03c49SAndrii Nakryiko ASSERT_OK_PTR(skel->links.handle_kretprobe_auto, "attach_kretprobe_auto"); 79*32c03c49SAndrii Nakryiko 80d3b0e3b0SAndrii Nakryiko if (!legacy) 814bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_before"); 824bd11e08SAndrii Nakryiko 834bd11e08SAndrii Nakryiko uprobe_opts.retprobe = false; 84d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 854bd11e08SAndrii Nakryiko uprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe, 861e8611bbSAndrii Nakryiko 0 /* self pid */, 871e8611bbSAndrii Nakryiko "/proc/self/exe", 884bd11e08SAndrii Nakryiko uprobe_offset, 894bd11e08SAndrii Nakryiko &uprobe_opts); 90bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uprobe_link, "attach_uprobe")) 911e8611bbSAndrii Nakryiko goto cleanup; 92f3c926a4SAndrii Nakryiko skel->links.handle_uprobe = uprobe_link; 93f3c926a4SAndrii Nakryiko 94d3b0e3b0SAndrii Nakryiko if (!legacy) 954bd11e08SAndrii Nakryiko ASSERT_GT(uprobe_ref_ctr, 0, "uprobe_ref_ctr_after"); 964bd11e08SAndrii Nakryiko 974bd11e08SAndrii Nakryiko /* if uprobe uses ref_ctr, uretprobe has to use ref_ctr as well */ 984bd11e08SAndrii Nakryiko uprobe_opts.retprobe = true; 99d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 1004bd11e08SAndrii Nakryiko uretprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe, 1011e8611bbSAndrii Nakryiko -1 /* any pid */, 1021e8611bbSAndrii Nakryiko "/proc/self/exe", 1034bd11e08SAndrii Nakryiko uprobe_offset, &uprobe_opts); 104bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uretprobe_link, "attach_uretprobe")) 1051e8611bbSAndrii Nakryiko goto cleanup; 106f3c926a4SAndrii Nakryiko skel->links.handle_uretprobe = uretprobe_link; 1071e8611bbSAndrii Nakryiko 108ba7499bcSAlan Maguire /* verify auto-attach fails for old-style uprobe definition */ 109ba7499bcSAlan Maguire uprobe_err_link = bpf_program__attach(skel->progs.handle_uprobe_byname); 110ba7499bcSAlan Maguire if (!ASSERT_EQ(libbpf_get_error(uprobe_err_link), -EOPNOTSUPP, 111ba7499bcSAlan Maguire "auto-attach should fail for old-style name")) 112ba7499bcSAlan Maguire goto cleanup; 113ba7499bcSAlan Maguire 114ba7499bcSAlan Maguire uprobe_opts.func_name = "trigger_func2"; 115ba7499bcSAlan Maguire uprobe_opts.retprobe = false; 116ba7499bcSAlan Maguire uprobe_opts.ref_ctr_offset = 0; 117ba7499bcSAlan Maguire skel->links.handle_uprobe_byname = 118ba7499bcSAlan Maguire bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe_byname, 119ba7499bcSAlan Maguire 0 /* this pid */, 120ba7499bcSAlan Maguire "/proc/self/exe", 121ba7499bcSAlan Maguire 0, &uprobe_opts); 122ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel->links.handle_uprobe_byname, "attach_uprobe_byname")) 123ba7499bcSAlan Maguire goto cleanup; 124ba7499bcSAlan Maguire 125ba7499bcSAlan Maguire /* verify auto-attach works */ 126ba7499bcSAlan Maguire skel->links.handle_uretprobe_byname = 127ba7499bcSAlan Maguire bpf_program__attach(skel->progs.handle_uretprobe_byname); 128ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel->links.handle_uretprobe_byname, "attach_uretprobe_byname")) 129ba7499bcSAlan Maguire goto cleanup; 130ba7499bcSAlan Maguire 131ba7499bcSAlan Maguire /* test attach by name for a library function, using the library 132ba7499bcSAlan Maguire * as the binary argument. libc.so.6 will be resolved via dlopen()/dlinfo(). 133ba7499bcSAlan Maguire */ 134ba7499bcSAlan Maguire uprobe_opts.func_name = "malloc"; 135ba7499bcSAlan Maguire uprobe_opts.retprobe = false; 136ba7499bcSAlan Maguire skel->links.handle_uprobe_byname2 = 137ba7499bcSAlan Maguire bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe_byname2, 138ba7499bcSAlan Maguire 0 /* this pid */, 139ba7499bcSAlan Maguire "libc.so.6", 140ba7499bcSAlan Maguire 0, &uprobe_opts); 141ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel->links.handle_uprobe_byname2, "attach_uprobe_byname2")) 142ba7499bcSAlan Maguire goto cleanup; 143ba7499bcSAlan Maguire 144ba7499bcSAlan Maguire uprobe_opts.func_name = "free"; 145ba7499bcSAlan Maguire uprobe_opts.retprobe = true; 146ba7499bcSAlan Maguire skel->links.handle_uretprobe_byname2 = 147ba7499bcSAlan Maguire bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe_byname2, 148ba7499bcSAlan Maguire -1 /* any pid */, 149ba7499bcSAlan Maguire "libc.so.6", 150ba7499bcSAlan Maguire 0, &uprobe_opts); 151ba7499bcSAlan Maguire if (!ASSERT_OK_PTR(skel->links.handle_uretprobe_byname2, "attach_uretprobe_byname2")) 152ba7499bcSAlan Maguire goto cleanup; 153ba7499bcSAlan Maguire 1541e8611bbSAndrii Nakryiko /* trigger & validate kprobe && kretprobe */ 1551e8611bbSAndrii Nakryiko usleep(1); 1561e8611bbSAndrii Nakryiko 157ba7499bcSAlan Maguire /* trigger & validate shared library u[ret]probes attached by name */ 158ba7499bcSAlan Maguire mem = malloc(1); 159ba7499bcSAlan Maguire free(mem); 1601e8611bbSAndrii Nakryiko 1611e8611bbSAndrii Nakryiko /* trigger & validate uprobe & uretprobe */ 162ff943683SAndrii Nakryiko trigger_func(); 1631e8611bbSAndrii Nakryiko 164ba7499bcSAlan Maguire /* trigger & validate uprobe attached by name */ 165ba7499bcSAlan Maguire trigger_func2(); 166ba7499bcSAlan Maguire 167ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->kprobe_res, 1, "check_kprobe_res"); 168*32c03c49SAndrii Nakryiko ASSERT_EQ(skel->bss->kprobe2_res, 11, "check_kprobe_auto_res"); 169ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->kretprobe_res, 2, "check_kretprobe_res"); 170*32c03c49SAndrii Nakryiko ASSERT_EQ(skel->bss->kretprobe2_res, 22, "check_kretprobe_auto_res"); 171ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uprobe_res, 3, "check_uprobe_res"); 172ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uretprobe_res, 4, "check_uretprobe_res"); 173ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uprobe_byname_res, 5, "check_uprobe_byname_res"); 174ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uretprobe_byname_res, 6, "check_uretprobe_byname_res"); 175ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uprobe_byname2_res, 7, "check_uprobe_byname2_res"); 176ba7499bcSAlan Maguire ASSERT_EQ(skel->bss->uretprobe_byname2_res, 8, "check_uretprobe_byname2_res"); 1771e8611bbSAndrii Nakryiko 1781e8611bbSAndrii Nakryiko cleanup: 179f3c926a4SAndrii Nakryiko test_attach_probe__destroy(skel); 1804bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_cleanup"); 1811e8611bbSAndrii Nakryiko } 182