5789a3f5911ee65bdf92891387f173719a1af47c
[lttng-tools.git] / tests / regression / kernel / test_select_poll_epoll
1 #!/bin/bash
2 #
3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4 #
5 # SPDX-License-Identifier: GPL-2.0-only
6 #
7
8 TEST_DESC="Kernel tracer - select, poll and epoll payload extraction"
9
10 CURDIR=$(dirname $0)/
11 TESTDIR=$CURDIR/../..
12 VALIDATE_SCRIPT="$CURDIR/validate_select_poll_epoll.py"
13 NUM_TESTS=102
14
15 # Only run this test on x86 and arm
16 uname -m | grep -E "x86|i686|arm|aarch64" >/dev/null 2>&1
17 if test $? != 0; then
18 plan_tests $NUM_TESTS
19 skip 0 "Run only on x86 and arm. Skipping all tests." $NUM_TESTS
20 exit 0
21 fi
22
23 DISABLE_VALIDATE=0
24 # Babeltrace python bindings are required for the validation, but
25 # it is not a mandatory dependancy of the project, so fail run the
26 # without the content validation, at least we test that we are not
27 # crashing the kernel.
28 $VALIDATE_SCRIPT --help >/dev/null 2>&1
29 if test $? != 0; then
30 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
31 DISABLE_VALIDATE=1
32 fi
33
34 LAST_WARNING=$(dmesg | grep " WARNING:" | cut -d' ' -f1 | tail -1)
35 LAST_OOPS=$(dmesg | grep " OOPS:" | cut -d' ' -f1 | tail -1)
36 LAST_BUG=$(dmesg | grep " BUG:" | cut -d' ' -f1 | tail -1)
37
38 source $TESTDIR/utils/utils.sh
39
40 function check_trace_content()
41 {
42 if test $DISABLE_VALIDATE == 1; then
43 ok 0 "Validation skipped"
44 return
45 fi
46
47 $VALIDATE_SCRIPT $@
48 if test $? = 0; then
49 ok 0 "Validation success"
50 else
51 fail "Validation"
52 fi
53 }
54
55 function test_working_cases()
56 {
57 TRACE_PATH=$(mktemp -d)
58 SESSION_NAME="syscall_payload"
59
60 # arm64 does not have epoll_wait
61 uname -m | grep -E "aarch64" >/dev/null 2>&1
62 if test $? = 0; then
63 SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
64 else
65 SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
66 fi
67
68 diag "Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
69
70 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
71
72 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
73 add_context_kernel_ok $SESSION_NAME channel0 pid
74
75 start_lttng_tracing_ok
76 { out=$(yes | $CURDIR/select_poll_epoll -t 1); } 2>/dev/null
77 stop_lttng_tracing_ok
78 pid=$(echo $out | cut -d' ' -f1)
79
80 validate_trace "$SYSCALL_LIST" $TRACE_PATH
81 check_trace_content -t 1 -p $pid $TRACE_PATH
82
83 destroy_lttng_session_ok $SESSION_NAME
84
85 rm -rf $TRACE_PATH
86 }
87
88 function test_timeout_cases()
89 {
90 TRACE_PATH=$(mktemp -d)
91 SESSION_NAME="syscall_payload"
92
93 # arm64 does not have epoll_wait
94 uname -m | grep -E "aarch64" >/dev/null 2>&1
95 if test $? = 0; then
96 SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
97 else
98 SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
99 fi
100
101 diag "Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
102
103 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
104
105 lttng_enable_kernel_syscall_ok $SESSION_NAME "$SYSCALL_LIST"
106 add_context_kernel_ok $SESSION_NAME channel0 pid
107
108 start_lttng_tracing_ok
109 { out=$($CURDIR/select_poll_epoll -t 2); } 2>/dev/null
110 stop_lttng_tracing_ok
111 pid=$(echo $out | cut -d' ' -f1)
112
113 validate_trace "$SYSCALL_LIST" $TRACE_PATH
114 check_trace_content -t 2 -p $pid $TRACE_PATH 2>/dev/null
115
116 destroy_lttng_session_ok $SESSION_NAME
117
118 rm -rf $TRACE_PATH
119 }
120
121 function test_pselect_invalid_fd()
122 {
123 TRACE_PATH=$(mktemp -d)
124 SESSION_NAME="syscall_payload"
125 SYSCALL_LIST="pselect6"
126
127 diag "pselect with invalid FD"
128
129 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
130
131 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
132 add_context_kernel_ok $SESSION_NAME channel0 pid
133
134 start_lttng_tracing_ok
135 { out=$($CURDIR/select_poll_epoll -t 3); } 2>/dev/null
136 stop_lttng_tracing_ok
137 pid=$(echo $out | cut -d' ' -f1)
138
139 validate_trace "$SYSCALL_LIST" $TRACE_PATH
140 check_trace_content -t 3 -p $pid $TRACE_PATH 2>/dev/null
141
142 destroy_lttng_session_ok $SESSION_NAME
143
144 rm -rf $TRACE_PATH
145 }
146
147 function test_big_ppoll()
148 {
149 TRACE_PATH=$(mktemp -d)
150 SESSION_NAME="syscall_payload"
151 SYSCALL_LIST="ppoll"
152
153 diag "ppoll with 2047 FDs"
154
155 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
156
157 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
158 add_context_kernel_ok $SESSION_NAME channel0 pid
159
160 start_lttng_tracing_ok
161 { out=$(yes | $CURDIR/select_poll_epoll -t 4); } 2>/dev/null
162 stop_lttng_tracing_ok
163 pid=$(echo $out | cut -d' ' -f1)
164
165 validate_trace "$SYSCALL_LIST" $TRACE_PATH
166 check_trace_content -t 4 -p $pid $TRACE_PATH 2>/dev/null
167
168 destroy_lttng_session_ok $SESSION_NAME
169
170 rm -rf $TRACE_PATH
171 }
172
173 function test_ppoll_overflow()
174 {
175 TRACE_PATH=$(mktemp -d)
176 SESSION_NAME="syscall_payload"
177 SYSCALL_LIST="ppoll"
178
179 diag "ppoll buffer overflow, should segfault, waits for input"
180
181 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
182
183 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
184 add_context_kernel_ok $SESSION_NAME channel0 pid
185
186 start_lttng_tracing_ok
187 diag "Expect segfaults"
188 { out=$(yes | $CURDIR/select_poll_epoll -t 5); } 2>/dev/null
189 stop_lttng_tracing_ok
190 echo $out
191 pid=$(echo $out | cut -d' ' -f1)
192
193 validate_trace "$SYSCALL_LIST" $TRACE_PATH
194
195 check_trace_content -t 5 -p $pid $TRACE_PATH 2>/dev/null
196
197 destroy_lttng_session_ok $SESSION_NAME
198
199 rm -rf $TRACE_PATH
200 }
201
202 function test_pselect_invalid_ptr()
203 {
204 TRACE_PATH=$(mktemp -d)
205 SESSION_NAME="syscall_payload"
206 SYSCALL_LIST="pselect6"
207
208 diag "pselect with invalid pointer, waits for input"
209
210 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
211
212 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
213 add_context_kernel_ok $SESSION_NAME channel0 pid
214
215 start_lttng_tracing_ok
216 { out=$(yes | $CURDIR/select_poll_epoll -t 6); } 2>/dev/null
217 stop_lttng_tracing_ok
218 pid=$(echo $out | cut -d' ' -f1)
219
220 validate_trace "$SYSCALL_LIST" $TRACE_PATH
221 check_trace_content -t 6 -p $pid $TRACE_PATH 2>/dev/null
222
223 destroy_lttng_session_ok $SESSION_NAME
224
225 rm -rf $TRACE_PATH
226 }
227
228 function test_ppoll_ulong_max()
229 {
230 TRACE_PATH=$(mktemp -d)
231 SESSION_NAME="syscall_payload"
232 SYSCALL_LIST="ppoll"
233
234 diag "ppoll with ulong_max fds, waits for input"
235
236 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
237
238 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
239 add_context_kernel_ok $SESSION_NAME channel0 pid
240
241 start_lttng_tracing_ok
242 { out=$(yes | $CURDIR/select_poll_epoll -t 7); } 2>/dev/null
243 stop_lttng_tracing_ok
244 pid=$(echo $out | cut -d' ' -f1)
245
246 validate_trace "$SYSCALL_LIST" $TRACE_PATH
247 check_trace_content -t 7 -p $pid $TRACE_PATH 2>/dev/null
248
249 destroy_lttng_session_ok $SESSION_NAME
250
251 rm -rf $TRACE_PATH
252 }
253
254 function test_epoll_pwait_invalid_ptr()
255 {
256 TRACE_PATH=$(mktemp -d)
257 SESSION_NAME="syscall_payload"
258 SYSCALL_LIST="epoll_pwait"
259
260 diag "epoll_pwait with invalid pointer, waits for input"
261
262 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
263
264 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
265 add_context_kernel_ok $SESSION_NAME channel0 pid
266
267 start_lttng_tracing_ok
268 { out=$(yes | $CURDIR/select_poll_epoll -t 8); } 2>/dev/null
269 stop_lttng_tracing_ok
270 pid=$(echo $out | cut -d' ' -f1)
271
272 validate_trace "$SYSCALL_LIST" $TRACE_PATH
273 check_trace_content -t 8 -p $pid $TRACE_PATH 2>/dev/null
274
275 destroy_lttng_session_ok $SESSION_NAME
276
277 rm -rf $TRACE_PATH
278 }
279
280 function test_epoll_pwait_int_max()
281 {
282 TRACE_PATH=$(mktemp -d)
283 SESSION_NAME="syscall_payload"
284 SYSCALL_LIST="epoll_pwait"
285
286 diag "epoll_pwait with maxevents set to INT_MAX, waits for input"
287
288 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
289
290 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
291 add_context_kernel_ok $SESSION_NAME channel0 pid
292
293 start_lttng_tracing_ok
294 { out=$(yes | $CURDIR/select_poll_epoll -t 9); } 2>/dev/null
295 stop_lttng_tracing_ok
296 pid=$(echo $out | cut -d' ' -f1)
297
298 validate_trace "$SYSCALL_LIST" $TRACE_PATH
299 check_trace_content -t 9 -p $pid $TRACE_PATH 2>/dev/null
300
301 destroy_lttng_session_ok $SESSION_NAME
302
303 rm -rf $TRACE_PATH
304 }
305
306 function test_ppoll_concurrent()
307 {
308 TRACE_PATH=$(mktemp -d)
309 SESSION_NAME="syscall_payload"
310 SYSCALL_LIST="ppoll"
311
312 diag "ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations), waits for input + timeout 1ms"
313
314 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
315
316 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
317 add_context_kernel_ok $SESSION_NAME channel0 pid
318
319 start_lttng_tracing_ok
320 { out=$(yes | $CURDIR/select_poll_epoll -t 10); } 2>/dev/null
321 stop_lttng_tracing_ok
322 pid=$(echo $out | cut -d' ' -f1)
323
324 validate_trace "$SYSCALL_LIST" $TRACE_PATH
325 check_trace_content -t 10 -p $pid $TRACE_PATH 2>/dev/null
326
327 destroy_lttng_session_ok $SESSION_NAME
328
329 rm -rf $TRACE_PATH
330 }
331
332 function test_epoll_pwait_concurrent()
333 {
334 TRACE_PATH=$(mktemp -d)
335 SESSION_NAME="syscall_payload"
336 SYSCALL_LIST="epoll_ctl,epoll_pwait"
337
338 diag "epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms"
339
340 create_lttng_session_ok $SESSION_NAME $TRACE_PATH
341
342 lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
343 add_context_kernel_ok $SESSION_NAME channel0 pid
344
345 start_lttng_tracing_ok
346 diag "Expect segfaults"
347 for i in $(seq 1 100); do
348 { out=$($CURDIR/select_poll_epoll -t 11); } 2>/dev/null
349 done
350 pid=$(echo $out | cut -d' ' -f1)
351 stop_lttng_tracing_ok
352
353 # epoll_wait is not always generated in the trace (stress test)
354 validate_trace "epoll_ctl" $TRACE_PATH
355 check_trace_content -t 11 -p $pid $TRACE_PATH 2>/dev/null
356
357 destroy_lttng_session_ok $SESSION_NAME
358
359 rm -rf $TRACE_PATH
360 }
361
362 # MUST set TESTDIR before calling those functions
363 plan_tests $NUM_TESTS
364
365 print_test_banner "$TEST_DESC"
366
367 if [ "$(id -u)" == "0" ]; then
368 isroot=1
369 else
370 isroot=0
371 fi
372
373 skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
374 {
375 validate_lttng_modules_present
376
377 start_lttng_sessiond
378
379 test_working_cases
380 test_timeout_cases
381 test_pselect_invalid_fd
382 test_big_ppoll
383 test_ppoll_overflow
384 test_pselect_invalid_ptr
385 test_ppoll_ulong_max
386 test_epoll_pwait_invalid_ptr
387 test_epoll_pwait_int_max
388 test_ppoll_concurrent
389 test_epoll_pwait_concurrent
390
391 stop_lttng_sessiond
392
393 NEW_WARNING=$(dmesg | grep " WARNING:" | cut -d' ' -f1 | tail -1)
394 NEW_OOPS=$(dmesg | grep " OOPS:" | cut -d' ' -f1 | tail -1)
395 NEW_BUG=$(dmesg | grep " BUG:" | cut -d' ' -f1 | tail -1)
396
397 if test "$LAST_WARNING" != "$NEW_WARNING"; then
398 fail "New WARNING generated"
399 fi
400 if test "$LAST_OOPS" != "$NEW_OOPS"; then
401 fail "New OOPS generated"
402 fi
403 if test "$LAST_BUG" != "$NEW_BUG"; then
404 fail "New BUG generated"
405 fi
406 }
This page took 0.03656 seconds and 3 git commands to generate.