3 # Copyright (C) - 2016 Julien Desfossez <jdesfossez@efficios.com>
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License, version 2 only, as
7 # published by the Free Software Foundation.
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 # You should have received a copy of the GNU General Public License along with
15 # this program; if not, write to the Free Software Foundation, Inc., 51
16 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 TEST_DESC
="Kernel tracer - select, poll and epoll payload extraction"
22 VALIDATE_SCRIPT
="$CURDIR/validate_select_poll_epoll.py"
25 # Only run this test on x86 and arm
26 uname
-m |
grep -E "x86|i686|arm|aarch64" >/dev
/null
2>&1
32 # Babeltrace python bindings are required for the validation, but
33 # it is not a mandatory dependancy of the project, so fail run the
34 # without the content validation, at least we test that we are not
35 # crashing the kernel.
36 $VALIDATE_SCRIPT --help >/dev
/null
2>&1
38 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
42 LAST_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
43 LAST_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
44 LAST_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
46 source $TESTDIR/utils
/utils.sh
48 function check_trace_content
()
50 if test $DISABLE_VALIDATE == 1; then
51 ok
0 "Validation skipped"
57 ok
0 "Validation success"
63 function test_working_cases
()
65 TRACE_PATH
=$
(mktemp
-d)
66 SESSION_NAME
="syscall_payload"
68 # arm64 does not have epoll_wait
69 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
71 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
73 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
76 diag
"Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
78 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
80 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
81 add_context_kernel_ok
$SESSION_NAME channel0 pid
83 start_lttng_tracing_ok
84 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 1); } 2>/dev
/null
86 pid
=$
(echo $out | cut
-d' ' -f1)
88 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
89 check_trace_content
-t 1 -p $pid $TRACE_PATH
91 destroy_lttng_session_ok
$SESSION_NAME
96 function test_timeout_cases
()
98 TRACE_PATH
=$
(mktemp
-d)
99 SESSION_NAME
="syscall_payload"
101 # arm64 does not have epoll_wait
102 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
104 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
106 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
109 diag
"Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
111 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
113 lttng_enable_kernel_syscall_ok
$SESSION_NAME "$SYSCALL_LIST"
114 add_context_kernel_ok
$SESSION_NAME channel0 pid
116 start_lttng_tracing_ok
117 { out
=$
($CURDIR/select_poll_epoll
-t 2); } 2>/dev
/null
118 stop_lttng_tracing_ok
119 pid
=$
(echo $out | cut
-d' ' -f1)
121 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
122 check_trace_content
-t 2 -p $pid $TRACE_PATH 2>/dev
/null
124 destroy_lttng_session_ok
$SESSION_NAME
129 function test_big_pselect
()
131 TRACE_PATH
=$
(mktemp
-d)
132 SESSION_NAME
="syscall_payload"
133 SYSCALL_LIST
="pselect6"
135 diag
"pselect with a FD > 1023"
137 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
139 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
140 add_context_kernel_ok
$SESSION_NAME channel0 pid
142 start_lttng_tracing_ok
143 { out
=$
($CURDIR/select_poll_epoll
-t 3); } 2>/dev
/null
144 stop_lttng_tracing_ok
145 pid
=$
(echo $out | cut
-d' ' -f1)
147 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
148 check_trace_content
-t 3 -p $pid $TRACE_PATH 2>/dev
/null
150 destroy_lttng_session_ok
$SESSION_NAME
155 function test_big_ppoll
()
157 TRACE_PATH
=$
(mktemp
-d)
158 SESSION_NAME
="syscall_payload"
161 diag
"ppoll with 2047 FDs"
163 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
165 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
166 add_context_kernel_ok
$SESSION_NAME channel0 pid
168 start_lttng_tracing_ok
169 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 4); } 2>/dev
/null
170 stop_lttng_tracing_ok
171 pid
=$
(echo $out | cut
-d' ' -f1)
173 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
174 check_trace_content
-t 4 -p $pid $TRACE_PATH 2>/dev
/null
176 destroy_lttng_session_ok
$SESSION_NAME
181 function test_ppoll_overflow
()
183 TRACE_PATH
=$
(mktemp
-d)
184 SESSION_NAME
="syscall_payload"
187 diag
"ppoll buffer overflow, should segfault, waits for input"
189 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
191 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
192 add_context_kernel_ok
$SESSION_NAME channel0 pid
194 start_lttng_tracing_ok
195 diag
"Expect segfaults"
196 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 5); } 2>/dev
/null
197 stop_lttng_tracing_ok
199 pid
=$
(echo $out | cut
-d' ' -f1)
201 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
203 check_trace_content
-t 5 -p $pid $TRACE_PATH 2>/dev
/null
205 destroy_lttng_session_ok
$SESSION_NAME
210 function test_pselect_invalid_ptr
()
212 TRACE_PATH
=$
(mktemp
-d)
213 SESSION_NAME
="syscall_payload"
214 SYSCALL_LIST
="pselect6"
216 diag
"pselect with invalid pointer, waits for input"
218 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
220 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
221 add_context_kernel_ok
$SESSION_NAME channel0 pid
223 start_lttng_tracing_ok
224 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 6); } 2>/dev
/null
225 stop_lttng_tracing_ok
226 pid
=$
(echo $out | cut
-d' ' -f1)
228 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
229 check_trace_content
-t 6 -p $pid $TRACE_PATH 2>/dev
/null
231 destroy_lttng_session_ok
$SESSION_NAME
236 function test_ppoll_ulong_max
()
238 TRACE_PATH
=$
(mktemp
-d)
239 SESSION_NAME
="syscall_payload"
242 diag
"ppoll with ulong_max fds, waits for input"
244 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
246 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
247 add_context_kernel_ok
$SESSION_NAME channel0 pid
249 start_lttng_tracing_ok
250 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 7); } 2>/dev
/null
251 stop_lttng_tracing_ok
252 pid
=$
(echo $out | cut
-d' ' -f1)
254 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
255 check_trace_content
-t 7 -p $pid $TRACE_PATH 2>/dev
/null
257 destroy_lttng_session_ok
$SESSION_NAME
262 function test_epoll_pwait_invalid_ptr
()
264 TRACE_PATH
=$
(mktemp
-d)
265 SESSION_NAME
="syscall_payload"
266 SYSCALL_LIST
="epoll_pwait"
268 diag
"epoll_pwait with invalid pointer, waits for input"
270 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
272 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
273 add_context_kernel_ok
$SESSION_NAME channel0 pid
275 start_lttng_tracing_ok
276 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 8); } 2>/dev
/null
277 stop_lttng_tracing_ok
278 pid
=$
(echo $out | cut
-d' ' -f1)
280 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
281 check_trace_content
-t 8 -p $pid $TRACE_PATH 2>/dev
/null
283 destroy_lttng_session_ok
$SESSION_NAME
288 function test_epoll_pwait_int_max
()
290 TRACE_PATH
=$
(mktemp
-d)
291 SESSION_NAME
="syscall_payload"
292 SYSCALL_LIST
="epoll_pwait"
294 diag
"epoll_pwait with maxevents set to INT_MAX, waits for input"
296 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
298 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
299 add_context_kernel_ok
$SESSION_NAME channel0 pid
301 start_lttng_tracing_ok
302 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 9); } 2>/dev
/null
303 stop_lttng_tracing_ok
304 pid
=$
(echo $out | cut
-d' ' -f1)
306 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
307 check_trace_content
-t 9 -p $pid $TRACE_PATH 2>/dev
/null
309 destroy_lttng_session_ok
$SESSION_NAME
314 function test_ppoll_concurrent
()
316 TRACE_PATH
=$
(mktemp
-d)
317 SESSION_NAME
="syscall_payload"
320 diag
"ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations), waits for input + timeout 1ms"
322 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
324 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
325 add_context_kernel_ok
$SESSION_NAME channel0 pid
327 start_lttng_tracing_ok
328 { out
=$
(yes |
$CURDIR/select_poll_epoll
-t 10); } 2>/dev
/null
329 stop_lttng_tracing_ok
330 pid
=$
(echo $out | cut
-d' ' -f1)
332 validate_trace
"$SYSCALL_LIST" $TRACE_PATH
333 check_trace_content
-t 10 -p $pid $TRACE_PATH 2>/dev
/null
335 destroy_lttng_session_ok
$SESSION_NAME
340 function test_epoll_pwait_concurrent
()
342 TRACE_PATH
=$
(mktemp
-d)
343 SESSION_NAME
="syscall_payload"
344 SYSCALL_LIST
="epoll_ctl,epoll_pwait"
346 diag
"epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms"
348 create_lttng_session_ok
$SESSION_NAME $TRACE_PATH
350 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
351 add_context_kernel_ok
$SESSION_NAME channel0 pid
353 start_lttng_tracing_ok
354 diag
"Expect segfaults"
355 for i
in $
(seq 1 100); do
356 { out
=$
($CURDIR/select_poll_epoll
-t 11); } 2>/dev
/null
358 pid
=$
(echo $out | cut
-d' ' -f1)
359 stop_lttng_tracing_ok
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 -p $pid $TRACE_PATH 2>/dev
/null
365 destroy_lttng_session_ok
$SESSION_NAME
370 # MUST set TESTDIR before calling those functions
371 plan_tests
$NUM_TESTS
373 print_test_banner
"$TEST_DESC"
375 if [ "$(id -u)" == "0" ]; then
381 skip
$isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
390 test_pselect_invalid_ptr
392 test_epoll_pwait_invalid_ptr
393 test_epoll_pwait_int_max
394 test_ppoll_concurrent
395 test_epoll_pwait_concurrent
399 NEW_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
400 NEW_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
401 NEW_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
403 if test "$LAST_WARNING" != "$NEW_WARNING"; then
404 fail
"New WARNING generated"
406 if test "$LAST_OOPS" != "$NEW_OOPS"; then
407 fail
"New OOPS generated"
409 if test "$LAST_BUG" != "$NEW_BUG"; then
410 fail
"New BUG generated"