3404195358192ce8551eaf3cdebafc7a18d42672
[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 DISABLE_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
21 if test $? != 0; then
22 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
23 DISABLE_VALIDATE=1
24 fi
25
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)
29
30 source $TESTDIR/utils/utils.sh
31
32 function 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
47 function 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
80 function 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
113 function test_pselect_invalid_fd()
114 {
115 TRACE_PATH=$(mktemp -d)
116 SESSION_NAME="syscall_payload"
117 SYSCALL_LIST="pselect6"
118
119 diag "pselect with invalid FD"
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
139 function 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
165 function 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
194 function 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
220 function 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
246 function 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
272 function 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
298 function 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
324 function 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
355 plan_tests $NUM_TESTS
356
357 print_test_banner "$TEST_DESC"
358
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
363 exit 0
364 fi
365
366 if [ "$(id -u)" == "0" ]; then
367 isroot=1
368 else
369 isroot=0
370 fi
371
372 skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
373 {
374 validate_lttng_modules_present
375
376 start_lttng_sessiond
377
378 test_working_cases
379 test_timeout_cases
380 test_pselect_invalid_fd
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.036687 seconds and 3 git commands to generate.