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