4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio_ext.h>
37 #include <sys/types.h>
41 /* evil knowledge of libc internals */
42 #include "../../../lib/libc/inc/thr_uberdata.h"
44 #define MAX_SYMNAMLEN 1024 /* Recommended max symbol name length */
46 static char *sigflags(int, int);
47 static int look(char *);
48 static void perr(char *);
49 static int usage(void);
50 static uintptr_t deinterpose(int, void *, psinfo_t
*, struct sigaction
*);
53 static char *procname
;
54 static int all_flag
= 0;
55 static int lookuphandlers_flag
= 1;
58 main(int argc
, char **argv
)
64 if ((command
= strrchr(argv
[0], '/')) != NULL
)
69 while ((c
= getopt(argc
, argv
, "an")) != EOF
) {
75 lookuphandlers_flag
= 0;
82 if (argc
- optind
< 1) {
87 * Make sure we'll have enough file descriptors to handle a target
88 * that has many many mappings.
90 if (getrlimit(RLIMIT_NOFILE
, &rlim
) == 0) {
91 rlim
.rlim_cur
= rlim
.rlim_max
;
92 (void) setrlimit(RLIMIT_NOFILE
, &rlim
);
93 (void) enable_extended_FILE_stdio(-1, -1);
96 for (; optind
!= argc
; optind
++) {
97 rc
+= look(argv
[optind
]);
106 (void) fprintf(stderr
, "usage:\t%s [-n] pid ...\n", command
);
107 (void) fprintf(stderr
, " (report process signal actions)\n");
113 uberdata_addr(struct ps_prochandle
*Pr
, char dmodel
)
117 if (Plookup_by_name(Pr
, "libc.so", "_tdb_bootstrap", &sym
) < 0)
120 if (dmodel
!= PR_MODEL_NATIVE
) {
124 if (Pread(Pr
, &addr
, sizeof (addr
), sym
.st_value
)
127 Pread(Pr
, &uaddr
, sizeof (uaddr
), (uintptr_t)addr
)
130 return ((uintptr_t)uaddr
);
133 if (dmodel
== PR_MODEL_NATIVE
) {
137 if (Pread(Pr
, &addr
, sizeof (addr
), sym
.st_value
)
140 Pread(Pr
, &uaddr
, sizeof (uaddr
), addr
)
145 if (Plookup_by_name(Pr
, "libc.so", "_uberdata", &sym
) < 0)
147 return (sym
.st_value
);
151 * Iterator function used to generate the process sigmask
152 * from the individual lwp sigmasks.
155 lwp_iter(void *cd
, const lwpstatus_t
*lwpstatus
)
159 ssp
->__sigbits
[0] &= lwpstatus
->pr_lwphold
.__sigbits
[0];
160 ssp
->__sigbits
[1] &= lwpstatus
->pr_lwphold
.__sigbits
[1];
161 ssp
->__sigbits
[2] &= lwpstatus
->pr_lwphold
.__sigbits
[2];
162 ssp
->__sigbits
[3] &= lwpstatus
->pr_lwphold
.__sigbits
[3];
165 * Return non-zero to terminate the iteration
166 * if the sigmask has become all zeros.
168 return ((ssp
->__sigbits
[0] | ssp
->__sigbits
[1] |
169 ssp
->__sigbits
[2] | ssp
->__sigbits
[3]) == 0);
181 struct sigaction
*action
= NULL
;
183 const psinfo_t
*psinfop
;
184 struct ps_prochandle
*Pr
= NULL
;
192 procname
= arg
; /* for perr() */
193 if ((Pr
= proc_arg_grab(arg
, PR_ARG_PIDS
, PGRAB_RDONLY
|PGRAB_FORCE
,
194 &gcode
)) == NULL
|| (psinfop
= Ppsinfo(Pr
)) == NULL
) {
195 (void) fprintf(stderr
, "%s: cannot examine %s: %s\n",
196 command
, arg
, Pgrab_error(gcode
));
199 (void) memcpy(&psinfo
, psinfop
, sizeof (psinfo_t
));
200 proc_unctrl_psinfo(&psinfo
);
202 (void) sprintf(pathname
, "/proc/%d/sigact", (int)psinfo
.pr_pid
);
203 if ((fd
= open(pathname
, O_RDONLY
)) < 0) {
208 if (fstat(fd
, &statb
) != 0) {
209 perr("fstat sigact");
212 maxsig
= statb
.st_size
/ sizeof (struct sigaction
);
213 action
= malloc(maxsig
* sizeof (struct sigaction
));
214 if (action
== NULL
) {
215 (void) fprintf(stderr
,
216 "%s: cannot malloc() space for %d sigaction structures\n",
220 if (read(fd
, (char *)action
, maxsig
* sizeof (struct sigaction
)) !=
221 maxsig
* sizeof (struct sigaction
)) {
228 (void) printf("%d:\t%.70s\n", (int)psinfo
.pr_pid
, psinfo
.pr_psargs
);
230 (void) sigfillset(&holdmask
);
231 (void) Plwp_iter(Pr
, lwp_iter
, &holdmask
);
233 if ((uberaddr
= uberdata_addr(Pr
, psinfo
.pr_dmodel
)) == 0) {
239 if (psinfo
.pr_dmodel
!= PR_MODEL_NATIVE
) {
241 aharraddr
= uberaddr
+
242 offsetof(uberdata32_t
, siguaction
);
243 aharrlen
= sizeof (siguaction32_t
) * NSIG
;
244 (void) Pread(Pr
, &addr
, sizeof (addr
),
245 uberaddr
+ offsetof(uberdata32_t
, sigacthandler
));
246 intfnaddr
= (uintptr_t)addr
;
250 aharraddr
= uberaddr
+
251 offsetof(uberdata_t
, siguaction
);
252 aharrlen
= sizeof (siguaction_t
) * NSIG
;
253 (void) Pread(Pr
, &intfnaddr
, sizeof (intfnaddr
),
254 uberaddr
+ offsetof(uberdata_t
, sigacthandler
));
259 aharr
= malloc(aharrlen
);
261 (void) fprintf(stderr
,
262 "%s: cannot malloc() space for actual handler array\n",
267 if (Pread(Pr
, aharr
, aharrlen
, aharraddr
) != aharrlen
) {
268 (void) fprintf(stderr
,
269 "%s: signal handler data at %p cannot be read.\n",
270 command
, (void *)aharraddr
);
276 for (sig
= 1; sig
<= maxsig
; sig
++) {
277 struct sigaction
*sp
= &action
[sig
- 1];
279 char buf
[SIG2STR_MAX
];
282 /* proc_signame() returns "SIG..."; skip the "SIG" part */
283 (void) printf("%s\t", proc_signame(sig
, buf
, sizeof (buf
)) + 3);
285 if (prismember(&holdmask
, sig
))
286 (void) printf("blocked,");
288 if (sp
->sa_handler
== SIG_DFL
)
289 (void) printf("default");
290 else if (sp
->sa_handler
== SIG_IGN
)
291 (void) printf("ignored");
295 if (caught
|| all_flag
) {
298 char hname
[MAX_SYMNAMLEN
];
299 char buf
[PRSIGBUFSZ
];
301 haddr
= (uintptr_t)sp
->sa_handler
;
303 if (aharr
&& intfnaddr
&& haddr
== intfnaddr
)
304 haddr
= deinterpose(sig
, aharr
, &psinfo
, sp
);
306 if (haddr
== (uintptr_t)SIG_DFL
) {
308 (void) printf("default");
310 } else if (haddr
== (uintptr_t)SIG_IGN
) {
312 (void) printf("ignored");
316 (void) printf("caught");
319 if (caught
|| all_flag
) {
320 if (lookuphandlers_flag
&& haddr
> 1 &&
321 Plookup_by_addr(Pr
, haddr
, hname
,
322 sizeof (hname
), &hsym
) == 0)
323 (void) printf("\t%-8s", hname
);
325 (void) printf("\t0x%-8lx",
328 s
= sigflags(sig
, sp
->sa_flags
);
329 (void) printf("%s", (*s
!= '\0')? s
: "\t0");
330 (void) proc_sigset2str(&sp
->sa_mask
, ",", 1,
333 (void) printf("\t%s", buf
);
335 } else if (sig
== SIGCLD
) {
337 sp
->sa_flags
& (SA_NOCLDWAIT
|SA_NOCLDSTOP
));
339 (void) printf("\t\t%s", s
);
362 (void) fprintf(stderr
, "%s: ", procname
);
369 sigflags(int sig
, int flags
)
371 static char code_buf
[100];
372 char *str
= code_buf
;
374 (SA_ONSTACK
|SA_RESETHAND
|SA_RESTART
|SA_SIGINFO
|SA_NODEFER
);
377 flagmask
|= (SA_NOCLDSTOP
|SA_NOCLDWAIT
);
380 if (flags
& ~flagmask
)
381 (void) sprintf(str
, ",0x%x,", flags
& ~flagmask
);
385 if (flags
& SA_RESTART
)
386 (void) strcat(str
, ",RESTART");
387 if (flags
& SA_RESETHAND
)
388 (void) strcat(str
, ",RESETHAND");
389 if (flags
& SA_ONSTACK
)
390 (void) strcat(str
, ",ONSTACK");
391 if (flags
& SA_SIGINFO
)
392 (void) strcat(str
, ",SIGINFO");
393 if (flags
& SA_NODEFER
)
394 (void) strcat(str
, ",NODEFER");
397 if (flags
& SA_NOCLDWAIT
)
398 (void) strcat(str
, ",NOCLDWAIT");
399 if (flags
& SA_NOCLDSTOP
)
400 (void) strcat(str
, ",NOCLDSTOP");
410 deinterpose(int sig
, void *aharr
, psinfo_t
*psinfo
, struct sigaction
*sp
)
412 if (sp
->sa_handler
== SIG_DFL
|| sp
->sa_handler
== SIG_IGN
)
413 return ((uintptr_t)sp
->sa_handler
);
415 if (psinfo
->pr_dmodel
!= PR_MODEL_NATIVE
) {
416 struct sigaction32
*sa32
= (struct sigaction32
*)
417 ((uintptr_t)aharr
+ sig
* sizeof (siguaction32_t
) +
418 offsetof(siguaction32_t
, sig_uaction
));
420 sp
->sa_flags
= sa32
->sa_flags
;
421 sp
->sa_handler
= (void (*)())(uintptr_t)sa32
->sa_handler
;
422 (void) memcpy(&sp
->sa_mask
, &sa32
->sa_mask
,
423 sizeof (sp
->sa_mask
));
427 struct sigaction
*sa
= (struct sigaction
*)
428 ((uintptr_t)aharr
+ sig
* sizeof (siguaction_t
) +
429 offsetof(siguaction_t
, sig_uaction
));
431 sp
->sa_flags
= sa
->sa_flags
;
432 sp
->sa_handler
= sa
->sa_handler
;
433 sp
->sa_mask
= sa
->sa_mask
;
435 return ((uintptr_t)sp
->sa_handler
);