@@ -25,14 +25,87 @@ noinline void uprobe_multi_func_3(void)
25
25
asm volatile ("" );
26
26
}
27
27
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 )
29
93
{
30
94
skel -> bss -> uprobe_multi_func_1_addr = (__u64 ) uprobe_multi_func_1 ;
31
95
skel -> bss -> uprobe_multi_func_2_addr = (__u64 ) uprobe_multi_func_2 ;
32
96
skel -> bss -> uprobe_multi_func_3_addr = (__u64 ) uprobe_multi_func_3 ;
33
97
34
98
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 );
36
109
37
110
/* trigger all probes */
38
111
uprobe_multi_func_1 ();
@@ -52,6 +125,9 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel)
52
125
ASSERT_EQ (skel -> bss -> uretprobe_multi_func_3_result , 2 , "uretprobe_multi_func_3_result" );
53
126
54
127
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" );
55
131
}
56
132
57
133
static void test_skel_api (void )
@@ -67,51 +143,69 @@ static void test_skel_api(void)
67
143
if (!ASSERT_OK (err , "uprobe_multi__attach" ))
68
144
goto cleanup ;
69
145
70
- uprobe_multi_test_run (skel );
146
+ uprobe_multi_test_run (skel , NULL );
71
147
72
148
cleanup :
73
149
uprobe_multi__destroy (skel );
74
150
}
75
151
76
152
static 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 )
78
155
{
156
+ pid_t pid = child ? child -> pid : -1 ;
79
157
struct uprobe_multi * skel = NULL ;
80
158
81
159
skel = uprobe_multi__open_and_load ();
82
160
if (!ASSERT_OK_PTR (skel , "uprobe_multi__open_and_load" ))
83
161
goto cleanup ;
84
162
85
163
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 ,
87
165
binary , pattern , opts );
88
166
if (!ASSERT_OK_PTR (skel -> links .uprobe , "bpf_program__attach_uprobe_multi" ))
89
167
goto cleanup ;
90
168
91
169
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 ,
93
171
binary , pattern , opts );
94
172
if (!ASSERT_OK_PTR (skel -> links .uretprobe , "bpf_program__attach_uprobe_multi" ))
95
173
goto cleanup ;
96
174
97
175
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 ,
99
177
binary , pattern , opts );
100
178
if (!ASSERT_OK_PTR (skel -> links .uprobe_sleep , "bpf_program__attach_uprobe_multi" ))
101
179
goto cleanup ;
102
180
103
181
opts -> retprobe = true;
104
182
skel -> links .uretprobe_sleep = bpf_program__attach_uprobe_multi (skel -> progs .uretprobe_sleep ,
105
- -1 , binary , pattern , opts );
183
+ pid , binary , pattern , opts );
106
184
if (!ASSERT_OK_PTR (skel -> links .uretprobe_sleep , "bpf_program__attach_uprobe_multi" ))
107
185
goto cleanup ;
108
186
109
- uprobe_multi_test_run (skel );
187
+ uprobe_multi_test_run (skel , child );
110
188
111
189
cleanup :
112
190
uprobe_multi__destroy (skel );
113
191
}
114
192
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
+
115
209
static void test_attach_api_pattern (void )
116
210
{
117
211
LIBBPF_OPTS (bpf_uprobe_multi_opts , opts );
@@ -134,7 +228,7 @@ static void test_attach_api_syms(void)
134
228
test_attach_api ("/proc/self/exe" , NULL , & opts );
135
229
}
136
230
137
- static void test_link_api ( void )
231
+ static void __test_link_api ( struct child * child )
138
232
{
139
233
int prog_fd , link1_fd = -1 , link2_fd = -1 , link3_fd = -1 , link4_fd = -1 ;
140
234
LIBBPF_OPTS (bpf_link_create_opts , opts );
@@ -155,6 +249,7 @@ static void test_link_api(void)
155
249
opts .uprobe_multi .path = path ;
156
250
opts .uprobe_multi .offsets = offsets ;
157
251
opts .uprobe_multi .cnt = ARRAY_SIZE (syms );
252
+ opts .uprobe_multi .pid = child ? child -> pid : 0 ;
158
253
159
254
skel = uprobe_multi__open_and_load ();
160
255
if (!ASSERT_OK_PTR (skel , "uprobe_multi__open_and_load" ))
@@ -184,7 +279,7 @@ static void test_link_api(void)
184
279
if (!ASSERT_GE (link4_fd , 0 , "link4_fd" ))
185
280
goto cleanup ;
186
281
187
- uprobe_multi_test_run (skel );
282
+ uprobe_multi_test_run (skel , child );
188
283
189
284
cleanup :
190
285
if (link1_fd >= 0 )
@@ -200,6 +295,21 @@ static void test_link_api(void)
200
295
free (offsets );
201
296
}
202
297
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
+
203
313
static void test_bench_attach_uprobe (void )
204
314
{
205
315
long attach_start_ns = 0 , attach_end_ns = 0 ;
0 commit comments