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