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"
15 # Babeltrace python bindings are required for the validation, but
16 # it is not a mandatory dependancy of the project, so fail run the
17 # without the content validation, at least we test that we are not
18 # crashing the kernel.
19 $VALIDATE_SCRIPT --help >/dev
/null
2>&1
21 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
25 LAST_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
26 LAST_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
27 LAST_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
29 SUPPORTED_SYSCALLS_LIST
=$
("$CURDIR"/select_poll_epoll
--list-supported-test-syscalls)
30 SUPPORTED_SYSCALLS_COUNT
=$
(echo $SUPPORTED_SYSCALLS_LIST |
awk -F '[\t,]' '{print NF}')
32 # Two tests validate their trace for every supported syscall
33 NUM_TESTS
=$
((88+(2*SUPPORTED_SYSCALLS_COUNT
)))
35 # shellcheck source=../../utils/utils.sh
36 source $TESTDIR/utils
/utils.sh
38 function check_trace_content
()
40 if test $DISABLE_VALIDATE == 1; then
41 ok
0 "Validation skipped"
47 ok
0 "Validation success"
53 function test_working_cases
()
55 SESSION_NAME
="syscall_payload"
56 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
57 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
59 diag
"Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
61 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
63 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SUPPORTED_SYSCALLS_LIST
64 add_context_kernel_ok
$SESSION_NAME channel0 pid
66 start_lttng_tracing_ok
67 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t working_cases
70 validate_trace
"$SUPPORTED_SYSCALLS_LIST" "$TRACE_PATH"
71 check_trace_content
-t working_cases
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH"
73 destroy_lttng_session_ok
$SESSION_NAME
76 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
79 function test_timeout_cases
()
81 SESSION_NAME
="syscall_payload"
82 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
83 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
85 diag
"Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
87 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
89 lttng_enable_kernel_syscall_ok
$SESSION_NAME "$SUPPORTED_SYSCALLS_LIST"
90 add_context_kernel_ok
$SESSION_NAME channel0 pid
92 start_lttng_tracing_ok
93 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t working_cases_timeout
96 validate_trace
"$SUPPORTED_SYSCALLS_LIST" "$TRACE_PATH"
97 check_trace_content
-t working_cases_timeout
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
99 destroy_lttng_session_ok
$SESSION_NAME
102 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
105 function test_pselect_invalid_fd
()
107 SESSION_NAME
="syscall_payload"
108 local SYSCALL_LIST
="pselect6"
109 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
110 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
112 diag
"pselect with invalid FD"
114 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
116 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
117 add_context_kernel_ok
$SESSION_NAME channel0 pid
119 start_lttng_tracing_ok
120 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t pselect_invalid_fd
121 stop_lttng_tracing_ok
123 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
124 check_trace_content
-t pselect_invalid_fd
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
126 destroy_lttng_session_ok
$SESSION_NAME
129 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
132 function test_ppoll_big
()
134 SESSION_NAME
="syscall_payload"
135 local SYSCALL_LIST
="ppoll"
136 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
137 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
139 diag
"ppoll with 2047 FDs"
141 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
143 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
144 add_context_kernel_ok
$SESSION_NAME channel0 pid
146 start_lttng_tracing_ok
147 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_big
148 stop_lttng_tracing_ok
150 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
151 check_trace_content
-t ppoll_big
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
153 destroy_lttng_session_ok
$SESSION_NAME
156 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
159 function test_ppoll_fds_buffer_overflow
()
161 SESSION_NAME
="syscall_payload"
162 local SYSCALL_LIST
="ppoll"
163 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
164 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
166 diag
"ppoll buffer overflow, should segfault, waits for input"
168 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
170 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
171 add_context_kernel_ok
$SESSION_NAME channel0 pid
173 start_lttng_tracing_ok
174 diag
"Expect segfaults"
175 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_fds_buffer_overflow
176 stop_lttng_tracing_ok
178 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
180 check_trace_content
-t ppoll_fds_buffer_overflow
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
182 destroy_lttng_session_ok
$SESSION_NAME
185 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
188 function test_pselect_invalid_pointer
()
190 SESSION_NAME
="syscall_payload"
191 local SYSCALL_LIST
="pselect6"
192 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
193 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
195 diag
"pselect with invalid pointer, waits for input"
197 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
199 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
200 add_context_kernel_ok
$SESSION_NAME channel0 pid
202 start_lttng_tracing_ok
203 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t pselect_invalid_pointer
204 stop_lttng_tracing_ok
206 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
207 check_trace_content
-t pselect_invalid_pointer
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
209 destroy_lttng_session_ok
$SESSION_NAME
212 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
215 function test_ppoll_fds_ulong_max
()
217 SESSION_NAME
="syscall_payload"
218 local SYSCALL_LIST
="ppoll"
219 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
220 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
222 diag
"ppoll with ulong_max fds, waits for input"
224 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
226 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
227 add_context_kernel_ok
$SESSION_NAME channel0 pid
229 start_lttng_tracing_ok
230 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_fds_ulong_max
231 stop_lttng_tracing_ok
233 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
234 check_trace_content
-t ppoll_fds_ulong_max
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
236 destroy_lttng_session_ok
$SESSION_NAME
239 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
242 function test_epoll_pwait_invalid_pointer
()
244 SESSION_NAME
="syscall_payload"
245 local SYSCALL_LIST
="epoll_pwait"
246 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
247 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
249 diag
"epoll_pwait with invalid pointer, waits for input"
251 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
253 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
254 add_context_kernel_ok
$SESSION_NAME channel0 pid
256 start_lttng_tracing_ok
257 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_invalid_pointer
258 stop_lttng_tracing_ok
260 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
261 check_trace_content
-t epoll_pwait_invalid_pointer
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
263 destroy_lttng_session_ok
$SESSION_NAME
266 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
269 function test_epoll_pwait_fds_int_max
()
271 SESSION_NAME
="syscall_payload"
272 local SYSCALL_LIST
="epoll_pwait"
273 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
274 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
276 diag
"epoll_pwait with maxevents set to INT_MAX, waits for input"
278 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
280 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
281 add_context_kernel_ok
$SESSION_NAME channel0 pid
283 start_lttng_tracing_ok
284 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_int_max
285 stop_lttng_tracing_ok
287 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
288 check_trace_content
-t epoll_pwait_int_max
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
290 destroy_lttng_session_ok
$SESSION_NAME
293 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
296 function test_ppoll_concurrent_write
()
298 SESSION_NAME
="syscall_payload"
299 local SYSCALL_LIST
="ppoll"
300 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
301 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
303 diag
"ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations), waits for input + timeout 1ms"
305 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
307 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
308 add_context_kernel_ok
$SESSION_NAME channel0 pid
310 start_lttng_tracing_ok
311 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_concurrent_write
312 stop_lttng_tracing_ok
314 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
315 check_trace_content
-t ppoll_concurrent_write
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
317 destroy_lttng_session_ok
$SESSION_NAME
320 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
323 function test_epoll_pwait_concurrent_unmap
()
325 SESSION_NAME
="syscall_payload"
326 local SYSCALL_LIST
="epoll_ctl,epoll_pwait"
327 TRACE_PATH
=$
(mktemp
-d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
328 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
-u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
330 diag
"epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms"
332 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
334 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
335 add_context_kernel_ok
$SESSION_NAME channel0 pid
337 start_lttng_tracing_ok
338 diag
"Expect segfaults"
339 for i
in $
(seq 1 100); do
340 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_concurrent_munmap
342 stop_lttng_tracing_ok
344 # epoll_wait is not always generated in the trace (stress test)
345 validate_trace
"epoll_ctl" "$TRACE_PATH"
346 check_trace_content
-t epoll_pwait_concurrent_munmap
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
348 destroy_lttng_session_ok
$SESSION_NAME
351 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
354 # MUST set TESTDIR before calling those functions
355 plan_tests
$NUM_TESTS
357 print_test_banner
"$TEST_DESC"
359 # Only run this test on x86 and arm
360 uname
-m |
grep -E "x86|i686|arm|aarch64" >/dev
/null
2>&1
361 if test $?
!= 0; then
362 skip
0 "Run only on x86 and arm. Skipping all tests." $NUM_TESTS
366 diag
"Supported syscalls are $SUPPORTED_SYSCALLS_LIST"
368 check_skip_kernel_test
"$NUM_TESTS" "Skipping all tests." ||
370 validate_lttng_modules_present
376 test_pselect_invalid_fd
378 test_ppoll_fds_buffer_overflow
379 test_pselect_invalid_pointer
380 test_ppoll_fds_ulong_max
381 test_epoll_pwait_invalid_pointer
382 test_epoll_pwait_fds_int_max
383 test_ppoll_concurrent_write
384 test_epoll_pwait_concurrent_unmap
388 NEW_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
389 NEW_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
390 NEW_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
392 if test "$LAST_WARNING" != "$NEW_WARNING"; then
393 diag
"Last WARNING before tests: ${LAST_WARNING}"
394 diag
"Last WARNING after tests: ${NEW_WARNING}"
395 fail
"New WARNING generated"
397 if test "$LAST_OOPS" != "$NEW_OOPS"; then
398 diag
"Last OOPS before tests: ${LAST_OOPS}"
399 diag
"Last OOPS after tests: ${NEW_OOPS}"
400 fail
"New OOPS generated"
402 if test "$LAST_BUG" != "$NEW_BUG"; then
403 diag
"Last BUG before tests: ${LAST_BUG}"
404 diag
"Last BUG after tests: ${NEW_BUG}"
405 fail
"New BUG generated"