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