diff options
author | kib <kib@FreeBSD.org> | 2010-03-22 09:29:56 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2010-03-22 09:29:56 +0000 |
commit | 2cb34af975fc03f49063752ff18c71611e4d29f4 (patch) | |
tree | 514fc8fef30d80cacfbb3abc8b8f05679075d348 /usr.bin/procstat | |
parent | 2b78eaab686552af48d3769a2a8cde96a9b056af (diff) | |
download | FreeBSD-src-2cb34af975fc03f49063752ff18c71611e4d29f4.zip FreeBSD-src-2cb34af975fc03f49063752ff18c71611e4d29f4.tar.gz |
MFC r204879:
Teach procstat(1) to display some information about signal disposition
and pending/blocked status for signals.
MFC r204880:
Add file forgotten in r204879.
Diffstat (limited to 'usr.bin/procstat')
-rw-r--r-- | usr.bin/procstat/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.1 | 61 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.c | 26 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.h | 4 | ||||
-rw-r--r-- | usr.bin/procstat/procstat_sigs.c | 139 |
5 files changed, 223 insertions, 8 deletions
diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile index 6cb5895..ddad5ed 100644 --- a/usr.bin/procstat/Makefile +++ b/usr.bin/procstat/Makefile @@ -9,6 +9,7 @@ SRCS= procstat.c \ procstat_cred.c \ procstat_files.c \ procstat_kstack.c \ + procstat_sigs.c \ procstat_threads.c \ procstat_vm.c diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index 0fdff9a..dab1c2b 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 20, 2008 +.Dd March 7, 2010 .Dt PROCSTAT 1 .Os .Sh NAME @@ -34,8 +34,9 @@ .Sh SYNOPSIS .Nm .Op Fl h +.Op Fl n .Op Fl w Ar interval -.Op Fl b | c | f | k | s | t | v +.Op Fl b | c | f | i | j | k | s | t | v .Op Fl a | Ar pid ... .Sh DESCRIPTION The @@ -56,6 +57,10 @@ Display binary information for the process. Display command line arguments for the process. .It Fl f Display file descriptor information for the process. +.It Fl i +Display signal pending and disposition information for the process. +.It Fl j +Display signal pending and blocked information for the process threads. .It Fl k Display the stacks of kernel threads in the process, excluding stacks of threads currently running on a CPU and threads with stacks swapped to disk. @@ -198,6 +203,58 @@ direct I/O .It l lock held .El +.Ss Signal Disposition Information +Display signal pending and disposition for a process: +.Pp +.Bl -tag -width ident -compact +.It PID +process ID +.It COMM +command +.It SIG +signal name +.It FLAGS +process signal disposition details, three symbols +.Bl -tag -width X -compact +.It P +if signal is pending in the global process queue, - otherwise +.It I +if signal delivery disposition is SIGIGN, - otherwise +.It C +if signal delivery is to catch it, - otherwise +.El +.El +.Pp +If +.Fl n +switch is given, the signal numbers are shown instead of signal names. +.Ss Thread Signal Information +Display signal pending and blocked for a process threads: +.Pp +.Bl -tag -width ident -compact +.It PID +process ID +.It COMM +command +.It TID +thread ID +.It SIG +signal name +.It FLAGS +thread signal delivery status, two symbols +.Bl -tag -width X -compact +.It P +if signal is pending for the thread, - otherwise +.It B +if signal is blocked in the thread signal mask, - if not blocked +.El +.El +.Pp +The +.Fl n +switch has the same effect as for the +.Fl i +switch, the signals numbers are shown instead of signal names. .Ss Kernel Thread Stacks Display kernel thread stacks for a process, allowing further interpretation of thread wait channels. diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index bc02682..ee95ae2 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -38,15 +38,15 @@ #include "procstat.h" -static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag; -int hflag; +static int aflag, bflag, cflag, fflag, iflag, jflag, kflag, sflag, tflag, vflag; +int hflag, nflag; static void usage(void) { - fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | " - "-k | -s | -t | -v]\n"); + fprintf(stderr, "usage: procstat [-h] [-n] [-w interval] [-b | -c | -f | " + "-i | -j | -k | -s | -t | -v]\n"); fprintf(stderr, " [-a | pid ...]\n"); exit(EX_USAGE); } @@ -61,6 +61,10 @@ procstat(pid_t pid, struct kinfo_proc *kipp) procstat_args(pid, kipp); else if (fflag) procstat_files(pid, kipp); + else if (iflag) + procstat_sigs(pid, kipp); + else if (jflag) + procstat_threads_sigs(pid, kipp); else if (kflag) procstat_kstack(pid, kipp, kflag); else if (sflag) @@ -109,7 +113,7 @@ main(int argc, char *argv[]) char *dummy; interval = 0; - while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) { + while ((ch = getopt(argc, argv, "abcfijknhstvw:")) != -1) { switch (ch) { case 'a': aflag++; @@ -127,10 +131,22 @@ main(int argc, char *argv[]) fflag++; break; + case 'i': + iflag++; + break; + + case 'j': + jflag++; + break; + case 'k': kflag++; break; + case 'n': + nflag++; + break; + case 'h': hflag++; break; diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h index 8bacab7..d73a203 100644 --- a/usr.bin/procstat/procstat.h +++ b/usr.bin/procstat/procstat.h @@ -29,7 +29,7 @@ #ifndef PROCSTAT_H #define PROCSTAT_H -extern int hflag; +extern int hflag, nflag; struct kinfo_proc; void kinfo_proc_sort(struct kinfo_proc *kipp, int count); @@ -40,7 +40,9 @@ void procstat_bin(pid_t pid, struct kinfo_proc *kipp); void procstat_cred(pid_t pid, struct kinfo_proc *kipp); void procstat_files(pid_t pid, struct kinfo_proc *kipp); void procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag); +void procstat_sigs(pid_t pid, struct kinfo_proc *kipp); void procstat_threads(pid_t pid, struct kinfo_proc *kipp); +void procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp); void procstat_vm(pid_t pid, struct kinfo_proc *kipp); #endif /* !PROCSTAT_H */ diff --git a/usr.bin/procstat/procstat_sigs.c b/usr.bin/procstat/procstat_sigs.c new file mode 100644 index 0000000..b1f5e35 --- /dev/null +++ b/usr.bin/procstat/procstat_sigs.c @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 2010 Konstantin Belousov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/user.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "procstat.h" + +static void +procstat_print_signame(int sig) +{ + char name[12]; + int i; + + if (!nflag && sig < sys_nsig) { + strlcpy(name, sys_signame[sig], sizeof(name)); + for (i = 0; name[i] != 0; i++) + name[i] = toupper(name[i]); + printf("%-7s ", name); + } else + printf("%-7d ", sig); +} + +static void +procstat_print_sig(const sigset_t *set, int sig, char flag) +{ + + printf("%c", sigismember(set, sig) ? flag : '-'); +} + +void +procstat_sigs(pid_t pid, struct kinfo_proc *kipp) +{ + int j; + + if (!hflag) + printf("%5s %-16s %-7s %4s\n", "PID", "COMM", "SIG", "FLAGS"); + + for (j = 1; j <= _SIG_MAXSIG; j++) { + printf("%5d ", pid); + printf("%-16s ", kipp->ki_comm); + procstat_print_signame(j); + printf(" "); + procstat_print_sig(&kipp->ki_siglist, j, 'P'); + procstat_print_sig(&kipp->ki_sigignore, j, 'I'); + procstat_print_sig(&kipp->ki_sigcatch, j, 'C'); + printf("\n"); + } +} + +void +procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp) +{ + struct kinfo_proc *kip; + int error, name[4], j; + unsigned int i; + size_t len; + + if (!hflag) + printf("%5s %6s %-16s %-7s %4s\n", "PID", "TID", "COMM", + "SIG", "FLAGS"); + + /* + * We need to re-query for thread information, so don't use *kipp. + */ + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD; + name[3] = pid; + + len = 0; + error = sysctl(name, 4, NULL, &len, NULL, 0); + if (error < 0 && errno != ESRCH) { + warn("sysctl: kern.proc.pid: %d", pid); + return; + } + if (error < 0) + return; + + kip = malloc(len); + if (kip == NULL) + err(-1, "malloc"); + + if (sysctl(name, 4, kip, &len, NULL, 0) < 0) { + warn("sysctl: kern.proc.pid: %d", pid); + free(kip); + return; + } + + kinfo_proc_sort(kip, len / sizeof(*kipp)); + for (i = 0; i < len / sizeof(*kipp); i++) { + kipp = &kip[i]; + for (j = 1; j <= _SIG_MAXSIG; j++) { + printf("%5d ", pid); + printf("%6d ", kipp->ki_tid); + printf("%-16s ", kipp->ki_comm); + procstat_print_signame(j); + printf(" "); + procstat_print_sig(&kipp->ki_siglist, j, 'P'); + procstat_print_sig(&kipp->ki_sigmask, j, 'B'); + printf("\n"); + } + } + free(kip); +} |