3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
5 # SPDX-License-Identifier: GPL-2.0-only
8 TEST_DESC
="Kernel tracer - select, poll and epoll payload extraction"
10 CURDIR
=$
(dirname "$0")/
12 VALIDATE_SCRIPT
="$CURDIR/validate_select_poll_epoll.py"
16 # Babeltrace python bindings are required for the validation, but
17 # it is not a mandatory dependancy of the project, so fail run the
18 # without the content validation, at least we test that we are not
19 # crashing the kernel.
20 $VALIDATE_SCRIPT --help >/dev
/null
2>&1
22 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
26 LAST_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
27 LAST_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
28 LAST_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
30 # shellcheck source=../../utils/utils.sh
31 source $TESTDIR/utils
/utils.sh
33 function check_trace_content
()
35 if test $DISABLE_VALIDATE == 1; then
36 ok
0 "Validation skipped"
42 ok
0 "Validation success"
48 function test_working_cases
()
50 SESSION_NAME
="syscall_payload"
51 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
52 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
54 # arm64 does not have epoll_wait
55 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
57 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
59 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
62 diag
"Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
64 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
66 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
67 add_context_kernel_ok
$SESSION_NAME channel0 pid
69 start_lttng_tracing_ok
70 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 1
73 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
74 check_trace_content
-t 1 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH"
76 destroy_lttng_session_ok
$SESSION_NAME
79 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
82 function test_timeout_cases
()
84 SESSION_NAME
="syscall_payload"
85 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
86 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
88 # arm64 does not have epoll_wait
89 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
91 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
93 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
96 diag
"Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
98 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
100 lttng_enable_kernel_syscall_ok
$SESSION_NAME "$SYSCALL_LIST"
101 add_context_kernel_ok
$SESSION_NAME channel0 pid
103 start_lttng_tracing_ok
104 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 2
105 stop_lttng_tracing_ok
107 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
108 check_trace_content
-t 2 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
110 destroy_lttng_session_ok
$SESSION_NAME
113 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
116 function test_pselect_invalid_fd
()
118 SESSION_NAME
="syscall_payload"
119 SYSCALL_LIST
="pselect6"
120 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
121 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
123 diag
"pselect with invalid FD"
125 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
127 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
128 add_context_kernel_ok
$SESSION_NAME channel0 pid
130 start_lttng_tracing_ok
131 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 3
132 stop_lttng_tracing_ok
134 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
135 check_trace_content
-t 3 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
137 destroy_lttng_session_ok
$SESSION_NAME
140 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
143 function test_big_ppoll
()
145 SESSION_NAME
="syscall_payload"
147 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
148 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
150 diag
"ppoll with 2047 FDs"
152 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
154 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
155 add_context_kernel_ok
$SESSION_NAME channel0 pid
157 start_lttng_tracing_ok
158 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 4
159 stop_lttng_tracing_ok
161 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
162 check_trace_content
-t 4 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
164 destroy_lttng_session_ok
$SESSION_NAME
167 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
170 function test_ppoll_overflow
()
172 SESSION_NAME
="syscall_payload"
174 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
175 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
177 diag
"ppoll buffer overflow, should segfault, waits for input"
179 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
181 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
182 add_context_kernel_ok
$SESSION_NAME channel0 pid
184 start_lttng_tracing_ok
185 diag
"Expect segfaults"
186 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 5
187 stop_lttng_tracing_ok
189 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
191 check_trace_content
-t 5 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
193 destroy_lttng_session_ok
$SESSION_NAME
196 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
199 function test_pselect_invalid_ptr
()
201 SESSION_NAME
="syscall_payload"
202 SYSCALL_LIST
="pselect6"
203 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
204 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
206 diag
"pselect with invalid pointer, waits for input"
208 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
210 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
211 add_context_kernel_ok
$SESSION_NAME channel0 pid
213 start_lttng_tracing_ok
214 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 6
215 stop_lttng_tracing_ok
217 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
218 check_trace_content
-t 6 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
220 destroy_lttng_session_ok
$SESSION_NAME
223 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
226 function test_ppoll_ulong_max
()
228 SESSION_NAME
="syscall_payload"
230 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
231 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
233 diag
"ppoll with ulong_max fds, waits for input"
235 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
237 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
238 add_context_kernel_ok
$SESSION_NAME channel0 pid
240 start_lttng_tracing_ok
241 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 7
242 stop_lttng_tracing_ok
244 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
245 check_trace_content
-t 7 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
247 destroy_lttng_session_ok
$SESSION_NAME
250 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
253 function test_epoll_pwait_invalid_ptr
()
255 SESSION_NAME
="syscall_payload"
256 SYSCALL_LIST
="epoll_pwait"
257 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
258 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
260 diag
"epoll_pwait with invalid pointer, waits for input"
262 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
264 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
265 add_context_kernel_ok
$SESSION_NAME channel0 pid
267 start_lttng_tracing_ok
268 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 8
269 stop_lttng_tracing_ok
271 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
272 check_trace_content
-t 8 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
274 destroy_lttng_session_ok
$SESSION_NAME
277 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
280 function test_epoll_pwait_int_max
()
282 SESSION_NAME
="syscall_payload"
283 SYSCALL_LIST
="epoll_pwait"
284 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
285 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
287 diag
"epoll_pwait with maxevents set to INT_MAX, waits for input"
289 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
291 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
292 add_context_kernel_ok
$SESSION_NAME channel0 pid
294 start_lttng_tracing_ok
295 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 9
296 stop_lttng_tracing_ok
298 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
299 check_trace_content
-t 9 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
301 destroy_lttng_session_ok
$SESSION_NAME
304 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
307 function test_ppoll_concurrent
()
309 SESSION_NAME
="syscall_payload"
311 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
312 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
314 diag
"ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations), waits for input + timeout 1ms"
316 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
318 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
319 add_context_kernel_ok
$SESSION_NAME channel0 pid
321 start_lttng_tracing_ok
322 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 10
323 stop_lttng_tracing_ok
325 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
326 check_trace_content
-t 10 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
328 destroy_lttng_session_ok
$SESSION_NAME
331 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
334 function test_epoll_pwait_concurrent
()
336 SESSION_NAME
="syscall_payload"
337 SYSCALL_LIST
="epoll_ctl,epoll_pwait"
338 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
339 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
341 diag
"epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms"
343 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
345 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
346 add_context_kernel_ok
$SESSION_NAME channel0 pid
348 start_lttng_tracing_ok
349 diag
"Expect segfaults"
350 for i
in $
(seq 1 100); do
351 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 11
353 stop_lttng_tracing_ok
355 # epoll_wait is not always generated in the trace (stress test)
356 validate_trace
"epoll_ctl" "$TRACE_PATH"
357 check_trace_content
-t 11 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
359 destroy_lttng_session_ok
$SESSION_NAME
362 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
365 # MUST set TESTDIR before calling those functions
366 plan_tests
$NUM_TESTS
368 print_test_banner
"$TEST_DESC"
370 # Only run this test on x86 and arm
371 uname
-m |
grep -E "x86|i686|arm|aarch64" >/dev
/null
2>&1
372 if test $?
!= 0; then
373 skip
0 "Run only on x86 and arm. Skipping all tests." $NUM_TESTS
377 if [ "$(id -u)" == "0" ]; then
383 skip
$isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
385 validate_lttng_modules_present
391 test_pselect_invalid_fd
394 test_pselect_invalid_ptr
396 test_epoll_pwait_invalid_ptr
397 test_epoll_pwait_int_max
398 test_ppoll_concurrent
399 test_epoll_pwait_concurrent
403 NEW_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
404 NEW_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
405 NEW_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
407 if test "$LAST_WARNING" != "$NEW_WARNING"; then
408 fail
"New WARNING generated"
410 if test "$LAST_OOPS" != "$NEW_OOPS"; then
411 fail
"New OOPS generated"
413 if test "$LAST_BUG" != "$NEW_BUG"; then
414 fail
"New BUG generated"