diff options
author | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
commit | d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2 (patch) | |
tree | b04f4bd7cd887f50e7d98af35f46b9834ff86c80 /usr.bin/procstat | |
parent | 3c8e37b1d04827f33c0c9a7594bd1b1ef7cdb3d3 (diff) | |
parent | 4fbde208c6460d576f64d6dc3cdc6cab085a4283 (diff) | |
download | FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.zip FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.tar.gz |
Merge head from 7/28
Diffstat (limited to 'usr.bin/procstat')
-rw-r--r-- | usr.bin/procstat/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.1 | 96 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.c | 25 | ||||
-rw-r--r-- | usr.bin/procstat/procstat.h | 3 | ||||
-rw-r--r-- | usr.bin/procstat/procstat_files.c | 7 | ||||
-rw-r--r-- | usr.bin/procstat/procstat_rusage.c | 161 | ||||
-rw-r--r-- | usr.bin/procstat/procstat_vm.c | 4 |
7 files changed, 271 insertions, 26 deletions
diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile index 505523e..4def311 100644 --- a/usr.bin/procstat/Makefile +++ b/usr.bin/procstat/Makefile @@ -11,6 +11,7 @@ SRCS= procstat.c \ procstat_files.c \ procstat_kstack.c \ procstat_rlimit.c \ + procstat_rusage.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 f06b2bc..f33c746 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 11, 2014 +.Dd May 16, 2014 .Dt PROCSTAT 1 .Os .Sh NAME @@ -33,11 +33,9 @@ .Nd get detailed process information .Sh SYNOPSIS .Nm -.Op Fl h -.Op Fl n -.Op Fl C +.Op Fl CHhn .Op Fl w Ar interval -.Op Fl b | c | e | f | i | j | k | l | s | t | v | x +.Op Fl b | c | e | f | i | j | k | l | r | s | t | v | x .Op Fl a | Ar pid | Ar core ... .Sh DESCRIPTION The @@ -65,7 +63,7 @@ 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. +Display signal pending and blocked information for the process's 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. @@ -73,6 +71,8 @@ If the flag is repeated, function offsets as well as function names are printed. .It Fl l Display resource limits for the process. +.It Fl r +Display resource usage information for the process. .It Fl s Display security credential information for the process. .It Fl t @@ -102,6 +102,13 @@ The flag requests the printing of additional capability information in the file descriptor view. .Pp +The +.Fl H +flag may be used to request per-thread statistics rather than per-process +statistics for some options. +For those options, the second field in the table will list the thread ID +to which the row of information corresponds. +.Pp Some information, such as VM and file descriptor information, is available only to the owner of a process or the superuser. .Ss Binary Information @@ -128,6 +135,17 @@ command .It ARGS command line arguments (if available) .El +.Ss Environment Variables +Display the process ID, command, and environment variables: +.Pp +.Bl -tag -width "ENVIRONMENT" -compact +.It PID +process ID +.It COMM +command +.It ENVIRONMENT +environment variables (if available) +.El .Ss File Descriptors Display detailed information about each file descriptor referenced by a process, including the process ID, command, file descriptor number, and @@ -237,7 +255,7 @@ present for each capability descriptor. .Ss Signal Disposition Information Display signal pending and disposition for a process: .Pp -.Bl -tag -width ident -compact +.Bl -tag -width indent -compact .It PID process ID .It COMM @@ -260,15 +278,15 @@ 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: +Display signal pending and blocked for a process's threads: .Pp -.Bl -tag -width ident -compact +.Bl -tag -width indent -compact .It PID process ID -.It COMM -command .It TID thread ID +.It COMM +command .It SIG signal name .It FLAGS @@ -285,7 +303,7 @@ The .Fl n switch has the same effect as for the .Fl i -switch, the signals numbers are shown instead of signal names. +switch: the signal 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. @@ -311,6 +329,45 @@ thread name .It KSTACK kernel thread call stack .El +.Ss Resource Limits +Display resource limits for a process: +.Pp +.Bl -tag -width indent -compact +.It PID +process ID +.It COMM +command +.It RLIMIT +resource limit name +.It SOFT +soft limit +.It HARD +hard limit +.El +.Ss Resource Usage +Display resource usage for a process. +If the +.Fl H +flag is specified, +resource usage for individual threads is displayed instead. +.Pp +.Bl -tag -width "RESOURCE" -compact +.It PID +process ID +.It TID +thread ID +.Po +if +.Fl H +is specified +.Pc +.It COMM +command +.It RESOURCE +resource name +.It VALUE +current usage +.El .Ss Security Credentials Display process credential information: .Pp @@ -388,7 +445,7 @@ private resident pages reference count .It SHD shadow page count -.It FL +.It FLAG mapping flags .It TP VM object type @@ -443,6 +500,19 @@ grows down (top-down stack) .It U grows up (bottom-up stack) .El +.Ss ELF Auxiliary Vector +Display ELF auxiliary vector values: +.Pp +.Bl -tag -width indent -compact +.It PID +process ID +.It COMM +command +.It AUXV +auxiliary vector name +.It VALUE +auxiliary vector value +.El .Sh EXIT STATUS .Ex -std .Sh SEE ALSO diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index 3c1dafa..de0237f 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -39,18 +39,19 @@ #include "procstat.h" -static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, sflag; -static int tflag, vflag, xflag; -int hflag, nflag, Cflag; +static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag; +static int sflag, tflag, vflag, xflag; +int hflag, nflag, Cflag, Hflag; static void usage(void) { - fprintf(stderr, "usage: procstat [-h] [-C] [-M core] [-N system] " + fprintf(stderr, "usage: procstat [-CHhn] [-M core] [-N system] " "[-w interval] \n"); fprintf(stderr, " [-b | -c | -e | -f | -i | -j | -k | " - "-l | -s | -t | -v | -x] [-a | pid | core ...]\n"); + "-l | -r | -s | -t | -v | -x]\n"); + fprintf(stderr, " [-a | pid | core ...]\n"); exit(EX_USAGE); } @@ -74,6 +75,8 @@ procstat(struct procstat *prstat, struct kinfo_proc *kipp) procstat_kstack(prstat, kipp, kflag); else if (lflag) procstat_rlimit(prstat, kipp); + else if (rflag) + procstat_rusage(prstat, kipp); else if (sflag) procstat_cred(prstat, kipp); else if (tflag) @@ -125,12 +128,16 @@ main(int argc, char *argv[]) interval = 0; memf = nlistf = NULL; - while ((ch = getopt(argc, argv, "CN:M:abcefijklhstvw:x")) != -1) { + while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrstvw:x")) != -1) { switch (ch) { case 'C': Cflag++; break; + case 'H': + Hflag++; + break; + case 'M': memf = optarg; break; @@ -181,6 +188,10 @@ main(int argc, char *argv[]) hflag++; break; + case 'r': + rflag++; + break; + case 's': sflag++; break; @@ -217,7 +228,7 @@ main(int argc, char *argv[]) /* We require that either 0 or 1 mode flags be set. */ tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) + - lflag + sflag + tflag + vflag + xflag; + lflag + rflag + sflag + tflag + vflag + xflag; if (!(tmp == 0 || tmp == 1)) usage(); diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h index 57c9cb5..98282b3 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, nflag, Cflag; +extern int hflag, nflag, Cflag, Hflag; struct kinfo_proc; void kinfo_proc_sort(struct kinfo_proc *kipp, int count); @@ -44,6 +44,7 @@ void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp, int kflag); void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp); +void procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads_sigs(struct procstat *prstat, struct kinfo_proc *kipp); diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c index af4f11f..85c51f3 100644 --- a/usr.bin/procstat/procstat_files.c +++ b/usr.bin/procstat/procstat_files.c @@ -114,7 +114,7 @@ addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) snprintf(buffer, buflen, "%s.%d", buffer2, ntohs(sin6->sin6_port)); else - strlcpy(buffer, "-", sizeof(buffer)); + strlcpy(buffer, "-", buflen); break; default: @@ -317,12 +317,12 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) if (!hflag) { if (Cflag) - printf("%5s %-16s %4s %1s %-9s %-*s " + printf("%5s %-16s %5s %1s %-8s %-*s " "%-3s %-12s\n", "PID", "COMM", "FD", "T", "FLAGS", capwidth, "CAPABILITIES", "PRO", "NAME"); else - printf("%5s %-16s %4s %1s %1s %-9s " + printf("%5s %-16s %5s %1s %1s %-8s " "%3s %7s %-3s %-12s\n", "PID", "COMM", "FD", "T", "V", "FLAGS", "REF", "OFFSET", "PRO", "NAME"); } @@ -450,6 +450,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) printf("%s", fst->fs_fflags & PS_FST_FFLAG_NONBLOCK ? "n" : "-"); printf("%s", fst->fs_fflags & PS_FST_FFLAG_DIRECT ? "d" : "-"); printf("%s", fst->fs_fflags & PS_FST_FFLAG_HASLOCK ? "l" : "-"); + printf(" "); if (!Cflag) { if (fst->fs_ref_count > -1) printf("%3d ", fst->fs_ref_count); diff --git a/usr.bin/procstat/procstat_rusage.c b/usr.bin/procstat/procstat_rusage.c new file mode 100644 index 0000000..b3c9d99 --- /dev/null +++ b/usr.bin/procstat/procstat_rusage.c @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2012 Advanced Computing Technologies LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/user.h> + +#include <libprocstat.h> +#include <stdbool.h> +#include <stdio.h> +#include <libutil.h> + +#include "procstat.h" + +static struct { + const char *ri_name; + bool ri_humanize; + int ri_scale; +} rusage_info[] = { + { "maximum RSS", true, 1 }, + { "integral shared memory", true, 1 }, + { "integral unshared data", true, 1 }, + { "integral unshared stack", true, 1 }, + { "page reclaims", false, 0 }, + { "page faults", false, 0 }, + { "swaps", false, 0 }, + { "block reads", false, 0 }, + { "block writes", false, 0 }, + { "messages sent", false, 0 }, + { "messages received", false, 0 }, + { "signals received", false, 0 }, + { "voluntary context switches", false, 0 }, + { "involuntary context switches", false, 0 } +}; + +/* xxx days hh:mm:ss.uuuuuu */ +static const char * +format_time(struct timeval *tv) +{ + static char buffer[32]; + int days, hours, minutes, seconds, used; + + minutes = tv->tv_sec / 60; + seconds = tv->tv_sec % 60; + hours = minutes / 60; + minutes %= 60; + days = hours / 24; + hours %= 24; + used = 0; + if (days == 1) + used += snprintf(buffer, sizeof(buffer), "1 day "); + else if (days > 0) + used += snprintf(buffer, sizeof(buffer), "%u days ", days); + + snprintf(buffer + used, sizeof(buffer) - used, "%02u:%02u:%02u.%06u ", + hours, minutes, seconds, (unsigned int)tv->tv_usec); + return (buffer); +} + +static const char * +format_value(long value, bool humanize, int scale) +{ + static char buffer[14]; + + if (scale != 0) + value <<= scale * 10; + if (humanize) + humanize_number(buffer, sizeof(buffer), value, "B", + scale, HN_DECIMAL); + else + snprintf(buffer, sizeof(buffer), "%ld ", value); + return (buffer); +} + +static void +print_prefix(struct kinfo_proc *kipp) +{ + + printf("%5d ", kipp->ki_pid); + if (Hflag) + printf("%6d ", kipp->ki_tid); + printf("%-16s ", kipp->ki_comm); +} + +static void +print_rusage(struct kinfo_proc *kipp) +{ + long *lp; + unsigned int i; + + print_prefix(kipp); + printf("%-14s %32s\n", "user time", + format_time(&kipp->ki_rusage.ru_utime)); + print_prefix(kipp); + printf("%-14s %32s\n", "system time", + format_time(&kipp->ki_rusage.ru_stime)); + lp = &kipp->ki_rusage.ru_maxrss; + for (i = 0; i < nitems(rusage_info); i++) { + print_prefix(kipp); + printf("%-32s %14s\n", rusage_info[i].ri_name, + format_value(*lp, rusage_info[i].ri_humanize, + rusage_info[i].ri_scale)); + lp++; + } +} + +void +procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp) +{ + struct kinfo_proc *kip; + unsigned int count, i; + + if (!hflag) { + printf("%5s ", "PID"); + if (Hflag) + printf("%6s ", "TID"); + printf("%-16s %-32s %14s\n", "COMM", "RESOURCE", + "VALUE "); + } + + if (!Hflag) { + print_rusage(kipp); + return; + } + + kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD, + kipp->ki_pid, &count); + if (kip == NULL) + return; + kinfo_proc_sort(kip, count); + for (i = 0; i < count; i++) + print_rusage(&kip[i]); + procstat_freeprocs(procstat, kip); +} diff --git a/usr.bin/procstat/procstat_vm.c b/usr.bin/procstat/procstat_vm.c index 80fe6a1..e4de492 100644 --- a/usr.bin/procstat/procstat_vm.c +++ b/usr.bin/procstat/procstat_vm.c @@ -50,9 +50,9 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) ptrwidth = 2*sizeof(void *) + 2; if (!hflag) - printf("%5s %*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n", + printf("%5s %*s %*s %3s %4s %4s %3s %3s %-4s %-2s %-s\n", "PID", ptrwidth, "START", ptrwidth, "END", "PRT", "RES", - "PRES", "REF", "SHD", "FL", "TP", "PATH"); + "PRES", "REF", "SHD", "FLAG", "TP", "PATH"); freep = procstat_getvmmap(procstat, kipp, &cnt); if (freep == NULL) |