]> granicus.if.org Git - strace/blob - sched.c
Remove XLAT_END
[strace] / sched.c
1 /*
2  * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
3  * Copyright (c) 2005 Roland McGrath <roland@redhat.com>
4  * Copyright (c) 2012-2015 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2014-2019 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: LGPL-2.1-or-later
9  */
10
11 #include "defs.h"
12
13 #include <sched.h>
14 #include "sched_attr.h"
15
16 #include "xlat/schedulers.h"
17 #include "xlat/sched_flags.h"
18
19 SYS_FUNC(sched_getscheduler)
20 {
21         if (entering(tcp)) {
22                 tprintf("%d", (int) tcp->u_arg[0]);
23         } else if (!syserror(tcp)) {
24                 tcp->auxstr = xlookup(schedulers, (kernel_ulong_t) tcp->u_rval);
25                 return RVAL_STR;
26         }
27         return 0;
28 }
29
30 SYS_FUNC(sched_setscheduler)
31 {
32         tprintf("%d, ", (int) tcp->u_arg[0]);
33         printxval(schedulers, tcp->u_arg[1], "SCHED_???");
34         tprints(", ");
35         printnum_int(tcp, tcp->u_arg[2], "%d");
36
37         return RVAL_DECODED;
38 }
39
40 SYS_FUNC(sched_getparam)
41 {
42         if (entering(tcp))
43                 tprintf("%d, ", (int) tcp->u_arg[0]);
44         else
45                 printnum_int(tcp, tcp->u_arg[1], "%d");
46         return 0;
47 }
48
49 SYS_FUNC(sched_setparam)
50 {
51         tprintf("%d, ", (int) tcp->u_arg[0]);
52         printnum_int(tcp, tcp->u_arg[1], "%d");
53
54         return RVAL_DECODED;
55 }
56
57 SYS_FUNC(sched_get_priority_min)
58 {
59         printxval(schedulers, tcp->u_arg[0], "SCHED_???");
60
61         return RVAL_DECODED;
62 }
63
64 static int
65 do_sched_rr_get_interval(struct tcb *const tcp,
66                          const print_obj_by_addr_fn print_ts)
67 {
68         if (entering(tcp)) {
69                 tprintf("%d, ", (int) tcp->u_arg[0]);
70         } else {
71                 if (syserror(tcp))
72                         printaddr(tcp->u_arg[1]);
73                 else
74                         print_ts(tcp, tcp->u_arg[1]);
75         }
76         return 0;
77 }
78
79 #if HAVE_ARCH_TIME32_SYSCALLS
80 SYS_FUNC(sched_rr_get_interval_time32)
81 {
82         return do_sched_rr_get_interval(tcp, print_timespec32);
83 }
84 #endif
85
86 SYS_FUNC(sched_rr_get_interval_time64)
87 {
88         return do_sched_rr_get_interval(tcp, print_timespec64);
89 }
90
91 static void
92 print_sched_attr(struct tcb *const tcp, const kernel_ulong_t addr,
93                  unsigned int usize)
94 {
95         struct sched_attr attr = {};
96         unsigned int size;
97
98         if (usize) {
99                 /* called from sched_getattr */
100                 size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
101                 if (umoven_or_printaddr(tcp, addr, size, &attr))
102                         return;
103                 /* the number of bytes written by the kernel */
104                 size = attr.size;
105         } else {
106                 /* called from sched_setattr */
107                 if (umove_or_printaddr(tcp, addr, &attr.size))
108                         return;
109                 usize = attr.size;
110                 if (!usize)
111                         usize = SCHED_ATTR_MIN_SIZE;
112                 size = usize <= sizeof(attr) ? usize : (unsigned) sizeof(attr);
113                 if (size >= SCHED_ATTR_MIN_SIZE) {
114                         if (umoven_or_printaddr(tcp, addr, size, &attr))
115                                 return;
116                 }
117         }
118
119         tprintf("{size=%u", attr.size);
120
121         if (size >= SCHED_ATTR_MIN_SIZE) {
122                 tprints(", sched_policy=");
123                 printxval(schedulers, attr.sched_policy, "SCHED_???");
124                 tprints(", sched_flags=");
125                 printflags64(sched_flags, attr.sched_flags, "SCHED_FLAG_???");
126
127 #define PRINT_SCHED_FIELD(field, fmt)                   \
128                 tprintf(", " #field "=%" fmt, attr.field)
129
130                 PRINT_SCHED_FIELD(sched_nice, "d");
131                 PRINT_SCHED_FIELD(sched_priority, "u");
132                 PRINT_SCHED_FIELD(sched_runtime, PRIu64);
133                 PRINT_SCHED_FIELD(sched_deadline, PRIu64);
134                 PRINT_SCHED_FIELD(sched_period, PRIu64);
135
136                 if (usize > size)
137                         tprints(", ...");
138         }
139
140         tprints("}");
141 }
142
143 SYS_FUNC(sched_setattr)
144 {
145         if (entering(tcp)) {
146                 tprintf("%d, ", (int) tcp->u_arg[0]);
147                 print_sched_attr(tcp, tcp->u_arg[1], 0);
148         } else {
149                 struct sched_attr attr;
150
151                 if (verbose(tcp) && tcp->u_error == E2BIG
152                     && umove(tcp, tcp->u_arg[1], &attr.size) == 0) {
153                         tprintf(" => {size=%u}", attr.size);
154                 }
155
156                 tprintf(", %u", (unsigned int) tcp->u_arg[2]);
157         }
158
159         return 0;
160 }
161
162 SYS_FUNC(sched_getattr)
163 {
164         if (entering(tcp)) {
165                 tprintf("%d, ", (int) tcp->u_arg[0]);
166         } else {
167                 const unsigned int size = tcp->u_arg[2];
168
169                 if (size)
170                         print_sched_attr(tcp, tcp->u_arg[1], size);
171                 else
172                         printaddr(tcp->u_arg[1]);
173                 tprints(", ");
174 #ifdef AARCH64
175                 /*
176                  * Due to a subtle gcc bug that leads to miscompiled aarch64
177                  * kernels, the 3rd argument of sched_getattr is not quite 32-bit
178                  * as on other architectures.  For more details see
179                  * https://lists.strace.io/pipermail/strace-devel/2017-March/006085.html
180                  */
181                 if (syserror(tcp))
182                         print_abnormal_hi(tcp->u_arg[2]);
183 #endif
184                 tprintf("%u", size);
185                 tprintf(", %u", (unsigned int) tcp->u_arg[3]);
186         }
187
188         return 0;
189 }