Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 : : * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 : : * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
5 : : * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 : : * Copyright (c) 2002-2004 Roland McGrath <roland@redhat.com>
7 : : * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
8 : : * Copyright (c) 2009-2013 Denys Vlasenko <dvlasenk@redhat.com>
9 : : * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
10 : : * All rights reserved.
11 : : *
12 : : * Redistribution and use in source and binary forms, with or without
13 : : * modification, are permitted provided that the following conditions
14 : : * are met:
15 : : * 1. Redistributions of source code must retain the above copyright
16 : : * notice, this list of conditions and the following disclaimer.
17 : : * 2. Redistributions in binary form must reproduce the above copyright
18 : : * notice, this list of conditions and the following disclaimer in the
19 : : * documentation and/or other materials provided with the distribution.
20 : : * 3. The name of the author may not be used to endorse or promote products
21 : : * derived from this software without specific prior written permission.
22 : : *
23 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 : : */
34 : :
35 : : #include "defs.h"
36 : :
37 : : #include <sys/wait.h>
38 : :
39 : : #include "xlat/wait4_options.h"
40 : :
41 : : #if !defined WCOREFLAG && defined WCOREFLG
42 : : # define WCOREFLAG WCOREFLG
43 : : #endif
44 : : #ifndef WCOREFLAG
45 : : # define WCOREFLAG 0x80
46 : : #endif
47 : : #ifndef WCOREDUMP
48 : : # define WCOREDUMP(status) ((status) & 0200)
49 : : #endif
50 : : #ifndef W_STOPCODE
51 : : # define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
52 : : #endif
53 : : #ifndef W_EXITCODE
54 : : # define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
55 : : #endif
56 : : #ifndef W_CONTINUED
57 : : # define W_CONTINUED 0xffff
58 : : #endif
59 : :
60 : : #include "ptrace.h"
61 : : #include "xlat/ptrace_events.h"
62 : :
63 : : static int
64 : 55 : printstatus(int status)
65 : : {
66 : 55 : int exited = 0;
67 : :
68 : : /*
69 : : * Here is a tricky presentation problem. This solution
70 : : * is still not entirely satisfactory but since there
71 : : * are no wait status constructors it will have to do.
72 : : */
73 [ + + ]: 55 : if (WIFSTOPPED(status)) {
74 : 10 : int sig = WSTOPSIG(status);
75 [ - + ]: 10 : tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s%s}",
76 : : signame(sig & 0x7f),
77 : 10 : sig & 0x80 ? " | 0x80" : "");
78 : 10 : status &= ~W_STOPCODE(sig);
79 : : }
80 [ + + ]: 45 : else if (WIFSIGNALED(status)) {
81 [ + + ]: 15 : tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
82 : : signame(WTERMSIG(status)),
83 : 15 : WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
84 : 15 : status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
85 : : }
86 [ + + ]: 30 : else if (WIFEXITED(status)) {
87 : 20 : tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
88 : 20 : WEXITSTATUS(status));
89 : 20 : exited = 1;
90 : 20 : status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
91 : : }
92 : : #ifdef WIFCONTINUED
93 [ + - ]: 10 : else if (WIFCONTINUED(status)) {
94 : 10 : tprints("[{WIFCONTINUED(s)}");
95 : 10 : status &= ~W_CONTINUED;
96 : : }
97 : : #endif
98 : : else {
99 : 0 : tprintf("[%#x]", status);
100 : 0 : return 0;
101 : : }
102 : :
103 [ - + ]: 55 : if (status) {
104 : 0 : unsigned int event = (unsigned int) status >> 16;
105 [ # # ]: 0 : if (event) {
106 : 0 : tprints(" | ");
107 : 0 : printxval(ptrace_events, event, "PTRACE_EVENT_???");
108 : 0 : tprints(" << 16");
109 : 0 : status &= 0xffff;
110 : : }
111 [ # # ]: 0 : if (status)
112 : 0 : tprintf(" | %#x", status);
113 : : }
114 : 55 : tprints("]");
115 : :
116 : 55 : return exited;
117 : : }
118 : :
119 : : static int
120 : 172 : printwaitn(struct tcb *const tcp,
121 : : void (*const print_rusage)(struct tcb *, kernel_ulong_t))
122 : : {
123 [ + + ]: 172 : if (entering(tcp)) {
124 : : /* On Linux, kernel-side pid_t is typedef'ed to int
125 : : * on all arches. Also, glibc-2.8 truncates wait3 and wait4
126 : : * pid argument to int on 64bit arches, producing,
127 : : * for example, wait4(4294967295, ...) instead of -1
128 : : * in strace. We have to use int here, not long.
129 : : */
130 : 86 : int pid = tcp->u_arg[0];
131 : 86 : tprintf("%d, ", pid);
132 : : } else {
133 : : int status;
134 : :
135 : : /* status */
136 [ + + ]: 86 : if (tcp->u_rval == 0)
137 : 20 : printaddr(tcp->u_arg[1]);
138 [ + + ]: 66 : else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &status))
139 : 55 : printstatus(status);
140 : : /* options */
141 : 86 : tprints(", ");
142 : 86 : printflags(wait4_options, tcp->u_arg[2], "W???");
143 [ + + ]: 86 : if (print_rusage) {
144 : : /* usage */
145 : 85 : tprints(", ");
146 [ + + ]: 85 : if (tcp->u_rval > 0)
147 : 55 : print_rusage(tcp, tcp->u_arg[3]);
148 : : else
149 : 86 : printaddr(tcp->u_arg[3]);
150 : : }
151 : : }
152 : 172 : return 0;
153 : : }
154 : :
155 : 2 : SYS_FUNC(waitpid)
156 : : {
157 : 2 : return printwaitn(tcp, NULL);
158 : : }
159 : :
160 : 170 : SYS_FUNC(wait4)
161 : : {
162 : 170 : return printwaitn(tcp, printrusage);
163 : : }
164 : :
165 : : #ifdef ALPHA
166 : : SYS_FUNC(osf_wait4)
167 : : {
168 : : return printwaitn(tcp, printrusage32);
169 : : }
170 : : #endif
171 : :
172 : : #include "xlat/waitid_types.h"
173 : :
174 : 160 : SYS_FUNC(waitid)
175 : : {
176 [ + + ]: 160 : if (entering(tcp)) {
177 : 80 : printxval(waitid_types, tcp->u_arg[0], "P_???");
178 : 80 : int pid = tcp->u_arg[1];
179 : 80 : tprintf(", %d, ", pid);
180 : : } else {
181 : : /* siginfo */
182 : 80 : printsiginfo_at(tcp, tcp->u_arg[2]);
183 : : /* options */
184 : 80 : tprints(", ");
185 : 80 : printflags(wait4_options, tcp->u_arg[3], "W???");
186 : : /* usage */
187 : 80 : tprints(", ");
188 : 80 : printrusage(tcp, tcp->u_arg[4]);
189 : : }
190 : 160 : return 0;
191 : : }
|