@@ -25,14 +25,87 @@ noinline void uprobe_multi_func_3(void)
2525 asm volatile ("" );
2626}
2727
28- static void uprobe_multi_test_run (struct uprobe_multi * skel )
28+ struct child {
29+ int go [2 ];
30+ int pid ;
31+ };
32+
33+ static void release_child (struct child * child )
34+ {
35+ int child_status ;
36+
37+ if (!child )
38+ return ;
39+ close (child -> go [1 ]);
40+ close (child -> go [0 ]);
41+ if (child -> pid > 0 )
42+ waitpid (child -> pid , & child_status , 0 );
43+ }
44+
45+ static void kick_child (struct child * child )
46+ {
47+ char c = 1 ;
48+
49+ if (child ) {
50+ write (child -> go [1 ], & c , 1 );
51+ release_child (child );
52+ }
53+ fflush (NULL );
54+ }
55+
56+ static struct child * spawn_child (void )
57+ {
58+ static struct child child ;
59+ int err ;
60+ int c ;
61+
62+ /* pipe to notify child to execute the trigger functions */
63+ if (pipe (child .go ))
64+ return NULL ;
65+
66+ child .pid = fork ();
67+ if (child .pid < 0 ) {
68+ release_child (& child );
69+ errno = EINVAL ;
70+ return NULL ;
71+ }
72+
73+ /* child */
74+ if (child .pid == 0 ) {
75+ close (child .go [1 ]);
76+
77+ /* wait for parent's kick */
78+ err = read (child .go [0 ], & c , 1 );
79+ if (err != 1 )
80+ exit (err );
81+
82+ uprobe_multi_func_1 ();
83+ uprobe_multi_func_2 ();
84+ uprobe_multi_func_3 ();
85+
86+ exit (errno );
87+ }
88+
89+ return & child ;
90+ }
91+
92+ static void uprobe_multi_test_run (struct uprobe_multi * skel , struct child * child )
2993{
3094 skel -> bss -> uprobe_multi_func_1_addr = (__u64 ) uprobe_multi_func_1 ;
3195 skel -> bss -> uprobe_multi_func_2_addr = (__u64 ) uprobe_multi_func_2 ;
3296 skel -> bss -> uprobe_multi_func_3_addr = (__u64 ) uprobe_multi_func_3 ;
3397
3498 skel -> bss -> user_ptr = test_data ;
35- skel -> bss -> pid = getpid ();
99+
100+ /*
101+ * Disable pid check in bpf program if we are pid filter test,
102+ * because the probe should be executed only by child->pid
103+ * passed at the probe attach.
104+ */
105+ skel -> bss -> pid = child ? 0 : getpid ();
106+
107+ if (child )
108+ kick_child (child );
36109
37110 /* trigger all probes */
38111 uprobe_multi_func_1 ();
@@ -52,6 +125,9 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel)
52125 ASSERT_EQ (skel -> bss -> uretprobe_multi_func_3_result , 2 , "uretprobe_multi_func_3_result" );
53126
54127 ASSERT_EQ (skel -> bss -> uprobe_multi_sleep_result , 6 , "uprobe_multi_sleep_result" );
128+
129+ if (child )
130+ ASSERT_EQ (skel -> bss -> child_pid , child -> pid , "uprobe_multi_child_pid" );
55131}
56132
57133static void test_skel_api (void )
@@ -67,51 +143,69 @@ static void test_skel_api(void)
67143 if (!ASSERT_OK (err , "uprobe_multi__attach" ))
68144 goto cleanup ;
69145
70- uprobe_multi_test_run (skel );
146+ uprobe_multi_test_run (skel , NULL );
71147
72148cleanup :
73149 uprobe_multi__destroy (skel );
74150}
75151
76152static void
77- test_attach_api (const char * binary , const char * pattern , struct bpf_uprobe_multi_opts * opts )
153+ __test_attach_api (const char * binary , const char * pattern , struct bpf_uprobe_multi_opts * opts ,
154+ struct child * child )
78155{
156+ pid_t pid = child ? child -> pid : -1 ;
79157 struct uprobe_multi * skel = NULL ;
80158
81159 skel = uprobe_multi__open_and_load ();
82160 if (!ASSERT_OK_PTR (skel , "uprobe_multi__open_and_load" ))
83161 goto cleanup ;
84162
85163 opts -> retprobe = false;
86- skel -> links .uprobe = bpf_program__attach_uprobe_multi (skel -> progs .uprobe , -1 ,
164+ skel -> links .uprobe = bpf_program__attach_uprobe_multi (skel -> progs .uprobe , pid ,
87165 binary , pattern , opts );
88166 if (!ASSERT_OK_PTR (skel -> links .uprobe , "bpf_program__attach_uprobe_multi" ))
89167 goto cleanup ;
90168
91169 opts -> retprobe = true;
92- skel -> links .uretprobe = bpf_program__attach_uprobe_multi (skel -> progs .uretprobe , -1 ,
170+ skel -> links .uretprobe = bpf_program__attach_uprobe_multi (skel -> progs .uretprobe , pid ,
93171 binary , pattern , opts );
94172 if (!ASSERT_OK_PTR (skel -> links .uretprobe , "bpf_program__attach_uprobe_multi" ))
95173 goto cleanup ;
96174
97175 opts -> retprobe = false;
98- skel -> links .uprobe_sleep = bpf_program__attach_uprobe_multi (skel -> progs .uprobe_sleep , -1 ,
176+ skel -> links .uprobe_sleep = bpf_program__attach_uprobe_multi (skel -> progs .uprobe_sleep , pid ,
99177 binary , pattern , opts );
100178 if (!ASSERT_OK_PTR (skel -> links .uprobe_sleep , "bpf_program__attach_uprobe_multi" ))
101179 goto cleanup ;
102180
103181 opts -> retprobe = true;
104182 skel -> links .uretprobe_sleep = bpf_program__attach_uprobe_multi (skel -> progs .uretprobe_sleep ,
105- -1 , binary , pattern , opts );
183+ pid , binary , pattern , opts );
106184 if (!ASSERT_OK_PTR (skel -> links .uretprobe_sleep , "bpf_program__attach_uprobe_multi" ))
107185 goto cleanup ;
108186
109- uprobe_multi_test_run (skel );
187+ uprobe_multi_test_run (skel , child );
110188
111189cleanup :
112190 uprobe_multi__destroy (skel );
113191}
114192
193+ static void
194+ test_attach_api (const char * binary , const char * pattern , struct bpf_uprobe_multi_opts * opts )
195+ {
196+ struct child * child ;
197+
198+ /* no pid filter */
199+ __test_attach_api (binary , pattern , opts , NULL );
200+
201+ /* pid filter */
202+ child = spawn_child ();
203+ if (!ASSERT_OK_PTR (child , "spawn_child" ))
204+ return ;
205+
206+ __test_attach_api (binary , pattern , opts , child );
207+ }
208+
115209static void test_attach_api_pattern (void )
116210{
117211 LIBBPF_OPTS (bpf_uprobe_multi_opts , opts );
@@ -134,7 +228,7 @@ static void test_attach_api_syms(void)
134228 test_attach_api ("/proc/self/exe" , NULL , & opts );
135229}
136230
137- static void test_link_api ( void )
231+ static void __test_link_api ( struct child * child )
138232{
139233 int prog_fd , link1_fd = -1 , link2_fd = -1 , link3_fd = -1 , link4_fd = -1 ;
140234 LIBBPF_OPTS (bpf_link_create_opts , opts );
@@ -155,6 +249,7 @@ static void test_link_api(void)
155249 opts .uprobe_multi .path = path ;
156250 opts .uprobe_multi .offsets = offsets ;
157251 opts .uprobe_multi .cnt = ARRAY_SIZE (syms );
252+ opts .uprobe_multi .pid = child ? child -> pid : 0 ;
158253
159254 skel = uprobe_multi__open_and_load ();
160255 if (!ASSERT_OK_PTR (skel , "uprobe_multi__open_and_load" ))
@@ -184,7 +279,7 @@ static void test_link_api(void)
184279 if (!ASSERT_GE (link4_fd , 0 , "link4_fd" ))
185280 goto cleanup ;
186281
187- uprobe_multi_test_run (skel );
282+ uprobe_multi_test_run (skel , child );
188283
189284cleanup :
190285 if (link1_fd >= 0 )
@@ -200,6 +295,21 @@ static void test_link_api(void)
200295 free (offsets );
201296}
202297
298+ void test_link_api (void )
299+ {
300+ struct child * child ;
301+
302+ /* no pid filter */
303+ __test_link_api (NULL );
304+
305+ /* pid filter */
306+ child = spawn_child ();
307+ if (!ASSERT_OK_PTR (child , "spawn_child" ))
308+ return ;
309+
310+ __test_link_api (child );
311+ }
312+
203313static void test_bench_attach_uprobe (void )
204314{
205315 long attach_start_ns = 0 , attach_end_ns = 0 ;
0 commit comments