3a62a1f1bba088da910d05a6a871f86c077d3628
[lttng-tools.git] / kernel / validate_select_poll_epoll.py
1 #!/usr/bin/env python3
2 #
3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4 #
5 # SPDX-License-Identifier: GPL-2.0-only
6 #
7
8 import argparse
9 import pprint
10 import sys
11 import time
12
13 from collections import defaultdict
14
15 NSEC_PER_SEC = 1000000000
16
17 try:
18 from babeltrace import TraceCollection
19 except ImportError:
20 # quick fix for debian-based distros
21 sys.path.append("/usr/local/lib/python%d.%d/site-packages" %
22 (sys.version_info.major, sys.version_info.minor))
23 from babeltrace import TraceCollection
24
25
26 class TraceParser:
27 def __init__(self, trace, pid):
28 self.trace = trace
29 self.pid = pid
30
31 # This dictionnary holds the results of each testcases of a test.
32 # Its layout is the following:
33 # self.expect={
34 # 'event_name_1': {'check_1': 0, 'check_2: 1},
35 # 'event_name_2': {'check_1': 1}
36 # }
37 # Each test classes checks the payload of different events. Each of
38 # those checks are stored in a event_name specific dictionnary in this
39 # data structure.
40 self.expect = defaultdict(lambda : defaultdict(int))
41
42 # This dictionnary holds the value recorded in the trace that are
43 # tested. Its content is use to print the values that caused a test to
44 # fail.
45 self.recorded_values = {}
46
47 def ns_to_hour_nsec(self, ns):
48 d = time.localtime(ns/NSEC_PER_SEC)
49 return "%02d:%02d:%02d.%09d" % (d.tm_hour, d.tm_min, d.tm_sec,
50 ns % NSEC_PER_SEC)
51
52 def parse(self):
53 # iterate over all the events
54 for event in self.trace.events:
55 if self.pid is not None and event["pid"] != self.pid:
56 continue
57
58 method_name = "handle_%s" % event.name.replace(":", "_").replace(
59 "+", "_")
60 # call the function to handle each event individually
61 if hasattr(TraceParser, method_name):
62 func = getattr(TraceParser, method_name)
63 func(self, event)
64
65 ret = 0
66 # For each event of the test case, check all entries for failed
67 for event_name, event_results in self.expect.items():
68 for val in event_results.keys():
69 if self.expect[event_name][val] == 0:
70 print("%s not validated" % val)
71 print("Values of the local variables of this test:")
72 # using pprint for pretty printing the dictionnary
73 pprint.pprint(self.recorded_values[event_name])
74 ret = 1
75
76 return ret
77
78 # epoll_ctl
79 def handle_compat_syscall_entry_epoll_ctl(self, event):
80 self.epoll_ctl_entry(event)
81
82 def handle_compat_syscall_exit_epoll_ctl(self, event):
83 self.epoll_ctl_exit(event)
84
85 def handle_syscall_entry_epoll_ctl(self, event):
86 self.epoll_ctl_entry(event)
87
88 def handle_syscall_exit_epoll_ctl(self, event):
89 self.epoll_ctl_exit(event)
90
91 def epoll_ctl_entry(self, event):
92 pass
93
94 def epoll_ctl_exit(self, event):
95 pass
96
97 # epoll_wait + epoll_pwait
98 def handle_compat_syscall_entry_epoll_wait(self, event):
99 self.epoll_wait_entry(event)
100
101 def handle_compat_syscall_exit_epoll_wait(self, event):
102 self.epoll_wait_exit(event)
103
104 def handle_syscall_entry_epoll_wait(self, event):
105 self.epoll_wait_entry(event)
106
107 def handle_syscall_exit_epoll_wait(self, event):
108 self.epoll_wait_exit(event)
109
110 def handle_compat_syscall_entry_epoll_pwait(self, event):
111 self.epoll_wait_entry(event)
112
113 def handle_compat_syscall_exit_epoll_pwait(self, event):
114 self.epoll_wait_exit(event)
115
116 def handle_syscall_entry_epoll_pwait(self, event):
117 self.epoll_wait_entry(event)
118
119 def handle_syscall_exit_epoll_pwait(self, event):
120 self.epoll_wait_exit(event)
121
122 def epoll_wait_entry(self, event):
123 pass
124
125 def epoll_wait_exit(self, event):
126 pass
127
128 ## poll + ppoll
129 def handle_compat_syscall_entry_poll(self, event):
130 self.poll_entry(event)
131
132 def handle_compat_syscall_exit_poll(self, event):
133 self.poll_exit(event)
134
135 def handle_syscall_entry_poll(self, event):
136 self.poll_entry(event)
137
138 def handle_syscall_exit_poll(self, event):
139 self.poll_exit(event)
140
141 def handle_compat_syscall_entry_ppoll(self, event):
142 self.poll_entry(event)
143
144 def handle_compat_syscall_exit_ppoll(self, event):
145 self.poll_exit(event)
146
147 def handle_syscall_entry_ppoll(self, event):
148 self.poll_entry(event)
149
150 def handle_syscall_exit_ppoll(self, event):
151 self.poll_exit(event)
152
153 def poll_entry(self, event):
154 pass
155
156 def poll_exit(self, event):
157 pass
158
159 # epoll_create
160 def handle_compat_syscall_entry_epoll_create1(self, event):
161 self.epoll_create_entry(event)
162
163 def handle_compat_syscall_exit_epoll_create1(self, event):
164 self.epoll_create_exit(event)
165
166 def handle_compat_syscall_entry_epoll_create(self, event):
167 self.epoll_create_entry(event)
168
169 def handle_compat_syscall_exit_epoll_create(self, event):
170 self.epoll_create_exit(event)
171
172 def handle_syscall_entry_epoll_create1(self, event):
173 self.epoll_create_entry(event)
174
175 def handle_syscall_exit_epoll_create1(self, event):
176 self.epoll_create_exit(event)
177
178 def handle_syscall_entry_epoll_create(self, event):
179 self.epoll_create_entry(event)
180
181 def handle_syscall_exit_epoll_create(self, event):
182 self.epoll_create_exit(event)
183
184 def epoll_create_entry(self, event):
185 pass
186
187 def epoll_create_exit(self, event):
188 pass
189
190 # select + pselect6
191 def handle_syscall_entry_pselect6(self, event):
192 self.select_entry(event)
193
194 def handle_syscall_exit_pselect6(self, event):
195 self.select_exit(event)
196
197 def handle_compat_syscall_entry_pselect6(self, event):
198 self.select_entry(event)
199
200 def handle_compat_syscall_exit_pselect6(self, event):
201 self.select_exit(event)
202
203 def handle_syscall_entry_select(self, event):
204 self.select_entry(event)
205
206 def handle_syscall_exit_select(self, event):
207 self.select_exit(event)
208
209 def handle_compat_syscall_entry_select(self, event):
210 self.select_entry(event)
211
212 def handle_compat_syscall_exit_select(self, event):
213 self.select_exit(event)
214
215 def select_entry(self, event):
216 pass
217
218 def select_exit(self, event):
219 pass
220
221
222 class Test1(TraceParser):
223 def __init__(self, trace, pid):
224 super().__init__(trace, pid)
225 self.expect["select_entry"]["select_in_fd0"] = 0
226 self.expect["select_entry"]["select_in_fd1023"] = 0
227 self.expect["select_exit"]["select_out_fd0"] = 0
228 self.expect["select_exit"]["select_out_fd1023"] = 0
229 self.expect["poll_entry"]["poll_in_nfds1"] = 0
230 self.expect["poll_exit"]["poll_out_nfds1"] = 0
231 self.expect["epoll_ctl_entry"]["epoll_ctl_in_add"] = 0
232 self.expect["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 0
233 self.expect["epoll_wait_entry"]["epoll_wait_in_ok"] = 0
234 self.expect["epoll_wait_exit"]["epoll_wait_out_fd0"] = 0
235
236 def select_entry(self, event):
237 n = event["n"]
238 overflow = event["overflow"]
239 readfd_0 = event["readfds"][0]
240
241 # check that the FD 0 is actually set in the readfds
242 if n == 1 and readfd_0 == 1:
243 self.expect["select_entry"]["select_in_fd0"] = 1
244 if n == 1023:
245 readfd_127 = event["readfds"][127]
246 writefd_127 = event["writefds"][127]
247 exceptfd_127 = event["exceptfds"][127]
248
249 # check that the FD 1023 is actually set in the readfds
250 if readfd_127 == 0x40 and writefd_127 == 0 and \
251 exceptfd_127 == 0 and overflow == 0:
252 self.expect["select_entry"]["select_in_fd1023"] = 1
253
254 # Save values of local variables to print in case of test failure
255 self.recorded_values["select_entry"] = locals()
256
257 def select_exit(self, event):
258 ret = event["ret"]
259 tvp = event["tvp"]
260 overflow = event["overflow"]
261 _readfds_length = event["_readfds_length"]
262
263 if ret == 1:
264 # check that the FD 0 is actually set in the readfds
265 readfd_0 = event["readfds"][0]
266
267 if readfd_0 == 1:
268 self.expect["select_exit"]["select_out_fd0"] = 1
269 # check that the FD 1023 is actually set in the readfds
270 if _readfds_length == 128:
271 readfd_127 = event["readfds"][127]
272 writefd_127 = event["writefds"][127]
273 exceptfd_127 = event["exceptfds"][127]
274 if readfd_127 == 0x40 and writefd_127 == 0 and \
275 exceptfd_127 == 0 and tvp == 0:
276 self.expect["select_exit"]["select_out_fd1023"] = 1
277
278 # Save values of local variables to print in case of test failure
279 self.recorded_values["select_exit"] = locals()
280
281 def poll_entry(self, event):
282 nfds = event["nfds"]
283 fds_length = event["fds_length"]
284 overflow = event["overflow"]
285
286 # check that only one FD is set, that it has the POLLIN flag and that
287 # the raw value matches the events bit field.
288 if nfds == 1 and fds_length == 1:
289 fd_0 = event["fds"][0]
290 if fd_0["raw_events"] == 0x3 and fd_0["events"]["POLLIN"] == 1 and \
291 fd_0["events"]["padding"] == 0:
292 self.expect["poll_entry"]["poll_in_nfds1"] = 1
293
294 # Save values of local variables to print in case of test failure
295 self.recorded_values["poll_entry"] = locals()
296
297 def poll_exit(self, event):
298 ret = event["ret"]
299 fds_length = event["fds_length"]
300
301 # check that only one FD is set, that it has the POLLIN flag and that
302 # the raw value matches the events bit field.
303 if ret == 1 and fds_length == 1:
304 fd_0 = event["fds"][0]
305 if fd_0["raw_events"] == 0x1 and fd_0["events"]["POLLIN"] == 1 and \
306 fd_0["events"]["padding"] == 0:
307 self.expect["poll_exit"]["poll_out_nfds1"] = 1
308
309 # Save values of local variables to print in case of test failure
310 self.recorded_values["poll_exit"] = locals()
311
312 def epoll_ctl_entry(self, event):
313 epfd = event["epfd"]
314 op_enum = event["op_enum"]
315 fd = event["fd"]
316 _event = event["event"]
317
318 # check that we have FD 0 waiting for EPOLLIN|EPOLLPRI and that
319 # data.fd = 0
320 if epfd == 3 and op_enum == "EPOLL_CTL_ADD" and fd == 0 and \
321 _event["data_union"]["fd"] == 0 and \
322 _event["events"]["EPOLLIN"] == 1 and \
323 _event["events"]["EPOLLPRI"] == 1:
324 self.expect["epoll_ctl_entry"]["epoll_ctl_in_add"] = 1
325
326 # Save values of local variables to print in case of test failure
327 self.recorded_values["epoll_ctl_entry"] = locals()
328
329 def epoll_ctl_exit(self, event):
330 ret = event["ret"]
331
332 if ret == 0:
333 self.expect["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 1
334
335 # Save values of local variables to print in case of test failure
336 self.recorded_values["epoll_ctl_exit"] = locals()
337
338 def epoll_wait_entry(self, event):
339 epfd = event["epfd"]
340 maxevents = event["maxevents"]
341 timeout = event["timeout"]
342
343 if epfd == 3 and maxevents == 1 and timeout == -1:
344 self.expect["epoll_wait_entry"]["epoll_wait_in_ok"] = 1
345
346 # Save values of local variables to print in case of test failure
347 self.recorded_values["epoll_wait_entry"] = locals()
348
349 def epoll_wait_exit(self, event):
350 ret = event["ret"]
351 fds_length = event["fds_length"]
352 overflow = event["overflow"]
353
354 # check that FD 0 returned with EPOLLIN and the right data.fd
355 if ret == 1 and fds_length == 1:
356 fd_0 = event["fds"][0]
357 if overflow == 0 and fd_0["data_union"]["fd"] == 0 and \
358 fd_0["events"]["EPOLLIN"] == 1:
359 self.expect["epoll_wait_exit"]["epoll_wait_out_fd0"] = 1
360
361 # Save values of local variables to print in case of test failure
362 self.recorded_values["epoll_wait_exit"] = locals()
363
364
365 class Test2(TraceParser):
366 def __init__(self, trace, pid):
367 super().__init__(trace, pid)
368 self.expect["select_entry"]["select_timeout_in_fd0"] = 0
369 self.expect["select_entry"]["select_timeout_in_fd1023"] = 0
370 self.expect["select_exit"]["select_timeout_out"] = 0
371 self.expect["poll_entry"]["poll_timeout_in"] = 0
372 self.expect["poll_exit"]["poll_timeout_out"] = 0
373 self.expect["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 0
374 self.expect["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 0
375 self.expect["epoll_wait_entry"]["epoll_wait_timeout_in"] = 0
376 self.expect["epoll_wait_exit"]["epoll_wait_timeout_out"] = 0
377
378 def select_entry(self, event):
379 n = event["n"]
380 tvp = event["tvp"]
381
382 if n == 1 and tvp != 0:
383 self.expect["select_entry"]["select_timeout_in_fd0"] = 1
384 if n == 1023:
385 readfd_127 = event["readfds"][127]
386 writefd_127 = event["writefds"][127]
387 exceptfd_127 = event["exceptfds"][127]
388
389 if readfd_127 == 0x40 and writefd_127 == 0 and \
390 exceptfd_127 == 0 and tvp != 0:
391 self.expect["select_entry"]["select_timeout_in_fd1023"] = 1
392
393 # Save values of local variables to print in case of test failure
394 self.recorded_values["select_entry"] = locals()
395
396 def select_exit(self, event):
397 ret = event["ret"]
398 tvp = event["tvp"]
399
400 if ret == 0 and tvp != 0:
401 self.expect["select_exit"]["select_timeout_out"] = 1
402
403 # Save values of local variables to print in case of test failure
404 self.recorded_values["select_exit"] = locals()
405
406 def poll_entry(self, event):
407 nfds = event["nfds"]
408 fds_length = event["fds_length"]
409
410 # check that we wait on FD 0 for POLLIN and that the raw_events
411 # field matches the value of POLLIN
412 if nfds == 1 and fds_length == 1:
413 fd_0 = event["fds"][0]
414 if fd_0["raw_events"] == 0x3 and \
415 fd_0["events"]["POLLIN"] == 1 and \
416 fd_0["events"]["padding"] == 0:
417 self.expect["poll_entry"]["poll_timeout_in"] = 1
418
419 # Save values of local variables to print in case of test failure
420 self.recorded_values["poll_entry"] = locals()
421
422 def poll_exit(self, event):
423 ret = event["ret"]
424 nfds = event["nfds"]
425 fds_length = event["fds_length"]
426
427 if ret == 0 and nfds == 1 and fds_length == 0:
428 self.expect["poll_exit"]["poll_timeout_out"] = 1
429
430 # Save values of local variables to print in case of test failure
431 self.recorded_values["poll_exit"] = locals()
432
433 def epoll_ctl_entry(self, event):
434 op_enum = event["op_enum"]
435 _event = event["event"]
436
437 # make sure we see a EPOLLIN|EPOLLPRI
438 if op_enum == "EPOLL_CTL_ADD" and \
439 _event["events"]["EPOLLIN"] == 1 and \
440 _event["events"]["EPOLLPRI"] == 1:
441 self.expect["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 1
442
443 # Save values of local variables to print in case of test failure
444 self.recorded_values["epoll_ctl_entry"] = locals()
445
446 def epoll_ctl_exit(self, event):
447 ret = event["ret"]
448
449 if ret == 0:
450 self.expect["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 1
451
452 # Save values of local variables to print in case of test failure
453 self.recorded_values["epoll_ctl_exit"] = locals()
454
455 def epoll_wait_entry(self, event):
456 maxevents = event["maxevents"]
457 timeout = event["timeout"]
458
459 if maxevents == 1 and timeout == 1:
460 self.expect["epoll_wait_entry"]["epoll_wait_timeout_in"] = 1
461
462 # Save values of local variables to print in case of test failure
463 self.recorded_values["epoll_wait_entry"] = locals()
464
465 def epoll_wait_exit(self, event):
466 ret = event["ret"]
467 fds_length = event["fds_length"]
468 overflow = event["overflow"]
469
470 if ret == 0 and fds_length == 0 and overflow == 0:
471 self.expect["epoll_wait_exit"]["epoll_wait_timeout_out"] = 1
472
473 # Save values of local variables to print in case of test failure
474 self.recorded_values["epoll_wait_exit"] = locals()
475
476
477 class Test3(TraceParser):
478 def __init__(self, trace, pid):
479 super().__init__(trace, pid)
480 self.expect["select_entry"]["select_invalid_fd_in"] = 0
481 self.expect["select_exit"]["select_invalid_fd_out"] = 0
482
483 def select_entry(self, event):
484 n = event["n"]
485 overflow = event["overflow"]
486
487 if n > 0 and overflow == 0:
488 self.expect["select_entry"]["select_invalid_fd_in"] = 1
489
490 # Save values of local variables to print in case of test failure
491 self.recorded_values["select_entry"] = locals()
492
493 def select_exit(self, event):
494 ret = event["ret"]
495 overflow = event["overflow"]
496 _readfds_length = event["_readfds_length"]
497
498 # make sure the event has a ret field equal to -EBADF
499 if ret == -9 and overflow == 0 and _readfds_length == 0:
500 self.expect["select_exit"]["select_invalid_fd_out"] = 1
501
502 # Save values of local variables to print in case of test failure
503 self.recorded_values["select_exit"] = locals()
504
505
506 class Test4(TraceParser):
507 def __init__(self, trace, pid):
508 super().__init__(trace, pid)
509 self.expect["poll_entry"]["big_poll_in"] = 0
510 self.expect["poll_exit"]["big_poll_out"] = 0
511
512 def poll_entry(self, event):
513 nfds = event["nfds"]
514 fds_length = event["fds_length"]
515 overflow = event["overflow"]
516
517 # test of big list of FDs and the behaviour of the overflow
518 if nfds == 2047 and fds_length == 512 and overflow == 1:
519 fd_0 = event["fds"][0]
520 fd_511 = event["fds"][511]
521 if fd_0["raw_events"] == 0x3 and fd_0["events"]["POLLIN"] == 1 and \
522 fd_0["events"]["padding"] == 0 and \
523 fd_511["events"]["POLLIN"] == 1 and \
524 fd_511["events"]["POLLPRI"] == 1:
525 self.expect["poll_entry"]["big_poll_in"] = 1
526
527 # Save values of local variables to print in case of test failure
528 self.recorded_values["poll_entry"] = locals()
529
530 def poll_exit(self, event):
531 ret = event["ret"]
532 nfds = event["nfds"]
533 fds_length = event["fds_length"]
534 overflow = event["overflow"]
535
536 # test of big list of FDs and the behaviour of the overflow
537 if ret == 2047 and nfds == 2047 and fds_length == 512 and overflow == 1:
538 fd_0 = event["fds"][0]
539 fd_511 = event["fds"][511]
540 if fd_0["events"]["POLLIN"] == 1 and fd_511["events"]["POLLIN"] == 1:
541 self.expect["poll_exit"]["big_poll_out"] = 1
542
543 # Save values of local variables to print in case of test failure
544 self.recorded_values["poll_exit"] = locals()
545
546 class Test5(TraceParser):
547 def __init__(self, trace, pid):
548 super().__init__(trace, pid)
549 self.expect["poll_entry"]["poll_overflow_in"] = 0
550 self.expect["poll_exit"]["poll_overflow_out"] = 0
551
552 def poll_entry(self, event):
553 nfds = event["nfds"]
554 fds_length = event["fds_length"]
555 overflow = event["overflow"]
556
557 # test that event in valid even though the target buffer is too small
558 # and the program segfaults
559 if nfds == 100 and fds_length == 100 and overflow == 0:
560 fd_0 = event["fds"][0]
561 if fd_0["events"]["POLLIN"] == 1:
562 self.expect["poll_entry"]["poll_overflow_in"] = 1
563
564 # Save values of local variables to print in case of test failure
565 self.recorded_values["poll_entry"] = locals()
566
567 def poll_exit(self, event):
568 nfds = event["nfds"]
569 overflow = event["overflow"]
570
571 # test that event in valid even though the target buffer is too small
572 # and the program segfaults
573 if nfds == 100 and overflow == 0:
574 self.expect["poll_exit"]["poll_overflow_out"] = 1
575
576 # Save values of local variables to print in case of test failure
577 self.recorded_values["poll_exit"] = locals()
578
579
580 class Test6(TraceParser):
581 def __init__(self, trace, pid):
582 super().__init__(trace, pid)
583 self.expect["select_entry"]["pselect_invalid_in"] = 0
584 self.expect["select_exit"]["pselect_invalid_out"] = 0
585
586 def select_entry(self, event):
587 n = event["n"]
588 overflow = event["overflow"]
589 _readfds_length = event["_readfds_length"]
590
591 # test that event in valid even though the target buffer pointer is
592 # invalid and the program segfaults
593 if n == 1 and overflow == 0 and _readfds_length == 0:
594 self.expect["select_entry"]["pselect_invalid_in"] = 1
595
596 # Save values of local variables to print in case of test failure
597 self.recorded_values["select_entry"] = locals()
598
599 def select_exit(self, event):
600 ret = event["ret"]
601 overflow = event["overflow"]
602 _readfds_length = event["_readfds_length"]
603
604 # test that event in valid even though the target buffer pointer is
605 # invalid and the program segfaults
606 if ret == -14 and overflow == 0 and _readfds_length == 0:
607 self.expect["select_exit"]["pselect_invalid_out"] = 1
608
609 # Save values of local variables to print in case of test failure
610 self.recorded_values["select_exit"] = locals()
611
612
613 class Test7(TraceParser):
614 def __init__(self, trace, pid):
615 super().__init__(trace, pid)
616 self.expect["poll_entry"]["poll_max_in"] = 0
617 self.expect["poll_exit"]["poll_max_out"] = 0
618
619 def poll_entry(self, event):
620 nfds = event["nfds"]
621 overflow = event["overflow"]
622
623 # check the proper working of INT_MAX maxevent value
624 if nfds == 4294967295 and overflow == 1:
625 self.expect["poll_entry"]["poll_max_in"] = 1
626
627 # Save values of local variables to print in case of test failure
628 self.recorded_values["poll_entry"] = locals()
629
630
631 def poll_exit(self, event):
632 ret = event["ret"]
633 nfds = event["nfds"]
634 overflow = event["overflow"]
635
636 # check the proper working of UINT_MAX maxevent value
637 if ret == -22 and nfds == 4294967295 and overflow == 0:
638 self.expect["poll_exit"]["poll_max_out"] = 1
639
640 # Save values of local variables to print in case of test failure
641 self.recorded_values["poll_exit"] = locals()
642
643
644 class Test8(TraceParser):
645 def __init__(self, trace, pid):
646 super().__init__(trace, pid)
647 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
648 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
649
650 def epoll_wait_entry(self, event):
651 epfd = event["epfd"]
652 maxevents = event["maxevents"]
653 timeout = event["timeout"]
654
655 # test that event in valid even though the target buffer pointer is
656 # invalid and the program segfaults
657 if epfd == 3 and maxevents == 1 and timeout == -1:
658 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 1
659
660 # Save values of local variables to print in case of test failure
661 self.recorded_values["epoll_wait_entry"] = locals()
662
663 def epoll_wait_exit(self, event):
664 ret = event["ret"]
665 fds_length = event["fds_length"]
666 overflow = event["overflow"]
667
668 # test that event in valid even though the target buffer pointer is
669 # invalid and the program segfaults
670 if ret == -14 and fds_length == 0 and overflow == 0:
671 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 1
672
673 # Save values of local variables to print in case of test failure
674 self.recorded_values["epoll_wait_exit"] = locals()
675
676
677 class Test9(TraceParser):
678 def __init__(self, trace, pid):
679 super().__init__(trace, pid)
680 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 0
681 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 0
682
683 def epoll_wait_entry(self, event):
684 epfd = event["epfd"]
685 maxevents = event["maxevents"]
686 timeout = event["timeout"]
687
688 # check the proper working of INT_MAX maxevent value
689 if epfd == 3 and maxevents == 2147483647 and timeout == -1:
690 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 1
691
692 # Save values of local variables to print in case of test failure
693 self.recorded_values["epoll_wait_entry"] = locals()
694
695 def epoll_wait_exit(self, event):
696 ret = event["ret"]
697 fds_length = event["fds_length"]
698 overflow = event["overflow"]
699
700 # check the proper working of INT_MAX maxevent value
701 if ret == -22 and fds_length == 0 and overflow == 0:
702 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 1
703
704 # Save values of local variables to print in case of test failure
705 self.recorded_values["epoll_wait_exit"] = locals()
706
707
708 if __name__ == "__main__":
709 parser = argparse.ArgumentParser(description='Trace parser')
710 parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
711 parser.add_argument('-t', '--test', type=int, help='Test to validate')
712 parser.add_argument('-p', '--pid', type=int, help='PID of the app')
713 args = parser.parse_args()
714
715 if not args.test:
716 print("Need to pass a test to validate (-t)")
717 sys.exit(1)
718
719 if not args.pid:
720 print("Need to pass the PID to check (-p)")
721 sys.exit(1)
722
723 traces = TraceCollection()
724 handle = traces.add_traces_recursive(args.path, "ctf")
725 if handle is None:
726 sys.exit(1)
727
728 t = None
729
730 if args.test == 1:
731 t = Test1(traces, args.pid)
732 elif args.test == 2:
733 t = Test2(traces, args.pid)
734 elif args.test == 3:
735 t = Test3(traces, args.pid)
736 elif args.test == 4:
737 t = Test4(traces, args.pid)
738 elif args.test == 5:
739 t = Test5(traces, args.pid)
740 elif args.test == 6:
741 t = Test6(traces, args.pid)
742 elif args.test == 7:
743 t = Test7(traces, args.pid)
744 elif args.test == 8:
745 t = Test8(traces, args.pid)
746 elif args.test == 9:
747 t = Test9(traces, args.pid)
748 elif args.test == 10:
749 # stress test, nothing reliable to check
750 ret = 0
751 elif args.test == 11:
752 # stress test, nothing reliable to check
753 ret = 0
754 else:
755 print("Invalid test case")
756 sys.exit(1)
757
758 if t is not None:
759 ret = t.parse()
760
761 for h in handle.values():
762 traces.remove_trace(h)
763
764 sys.exit(ret)
This page took 0.074199 seconds and 4 git commands to generate.