Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 May 2013 19:05:28 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r250871 - stable/9/usr.bin/procstat
Message-ID:  <201305211905.r4LJ5SU6016158@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Tue May 21 19:05:27 2013
New Revision: 250871
URL: http://svnweb.freebsd.org/changeset/base/250871

Log:
  MFC r249668, r249669, r249671, r249673, r249675, r249678, r249680, r249683,
      r249685, r249686:
  
  r249668:
  
  Use procstat_getprocs(3) for retrieving thread information instead of
  direct sysctl calls.
  
  r249669:
  
  Use more generic procstat_getvmmap(3) for retrieving VM layout of a process.
  
  r249671:
  
  Use procstat_getgroups(3) for retrieving groups information instead of
  direct sysctl.
  
  r249673:
  
  Use procstat_getumask(3) for retrieving umaks information instead of
  direct sysctl.
  
  r249675:
  
  Use procstat_getrlimit(3) for retrieving rlimit information instead of
  direct sysctl calls.
  
  r249678:
  
  Use libprocstat(3) when retrieving binary information for a process.
  
  r249680:
  
  Use libprocstat(3) to retrieve process command line arguments and
  environment variables.
  
  r249683:
  
  Use libprocstat(3) to retrieve ELF auxiliary vector.
  
  r249685:
  
  Use procstat_getkstack(3) for retrieving process kernel stacks
  instead of direct sysctl calls.
  
  r249686:
  
  Make use of newly added libprocstat(3) ability to extract procstat
  info from a process core file.
  
  So now one can run procstat(1) on a process core e.g. to get a list of
  files opened by a process when it crashed:
  
  root@lisa:/ # procstat -f /root/vi.core
    PID COMM               FD T V FLAGS     REF  OFFSET PRO NAME
    658 vi               text v r r--------   -       - -   /usr/bin/vi
    658 vi               ctty v c rw-------   -       - -   /dev/pts/0
    658 vi                cwd v d r--------   -       - -   /root
    658 vi               root v d r--------   -       - -   /
    658 vi                  0 v c rw-------  11    3208 -   /dev/pts/0
    658 vi                  1 v c rw-------  11    3208 -   /dev/pts/0
    658 vi                  2 v c rw-------  11    3208 -   /dev/pts/0
    658 vi                  3 v r r----n-l-   1       0 -   /tmp/vi.0AYKz3Lps7
    658 vi                  4 v r rw-------   1       0 -   /var/tmp/vi.recover/vi.GaGYsz
    658 vi                  5 v r rw-------   1       0 -   -
  
  PR:		kern/173723
  Suggested by:	jhb

Modified:
  stable/9/usr.bin/procstat/procstat.1
  stable/9/usr.bin/procstat/procstat.c
  stable/9/usr.bin/procstat/procstat.h
  stable/9/usr.bin/procstat/procstat_args.c
  stable/9/usr.bin/procstat/procstat_auxv.c
  stable/9/usr.bin/procstat/procstat_bin.c
  stable/9/usr.bin/procstat/procstat_cred.c
  stable/9/usr.bin/procstat/procstat_kstack.c
  stable/9/usr.bin/procstat/procstat_rlimit.c
  stable/9/usr.bin/procstat/procstat_sigs.c
  stable/9/usr.bin/procstat/procstat_threads.c
  stable/9/usr.bin/procstat/procstat_vm.c
Directory Properties:
  stable/9/usr.bin/procstat/   (props changed)

Modified: stable/9/usr.bin/procstat/procstat.1
==============================================================================
--- stable/9/usr.bin/procstat/procstat.1	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat.1	Tue May 21 19:05:27 2013	(r250871)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 11, 2012
+.Dd April 20, 2013
 .Dt PROCSTAT 1
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 .Op Fl C
 .Op Fl w Ar interval
 .Op Fl b | c | e | f | i | j | k | l | s | t | v | x
-.Op Fl a | Ar pid ...
+.Op Fl a | Ar pid | Ar core ...
 .Sh DESCRIPTION
 The
 .Nm
@@ -47,6 +47,8 @@ utility displays detailed information ab
 arguments, or if the
 .Fl a
 flag is used, all processes.
+It can also display information extracted from a process core file, if
+the core file is specified as the argument.
 .Pp
 By default, basic process statistics are printed; one of the following
 options may be specified in order to select more detailed process information

Modified: stable/9/usr.bin/procstat/procstat.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat.c	Tue May 21 19:05:27 2013	(r250871)
@@ -50,7 +50,7 @@ usage(void)
 	fprintf(stderr, "usage: procstat [-h] [-C] [-M core] [-N system] "
 	    "[-w interval] \n");
 	fprintf(stderr, "                [-b | -c | -e | -f | -i | -j | -k | "
-	    "-l | -s | -t | -v | -x] [-a | pid ...]\n");
+	    "-l | -s | -t | -v | -x] [-a | pid | core ...]\n");
 	exit(EX_USAGE);
 }
 
@@ -59,11 +59,11 @@ procstat(struct procstat *prstat, struct
 {
 
 	if (bflag)
-		procstat_bin(kipp);
+		procstat_bin(prstat, kipp);
 	else if (cflag)
-		procstat_args(kipp);
+		procstat_args(prstat, kipp);
 	else if (eflag)
-		procstat_env(kipp);
+		procstat_env(prstat, kipp);
 	else if (fflag)
 		procstat_files(prstat, kipp);
 	else if (iflag)
@@ -71,17 +71,17 @@ procstat(struct procstat *prstat, struct
 	else if (jflag)
 		procstat_threads_sigs(prstat, kipp);
 	else if (kflag)
-		procstat_kstack(kipp, kflag);
+		procstat_kstack(prstat, kipp, kflag);
 	else if (lflag)
-		procstat_rlimit(kipp);
+		procstat_rlimit(prstat, kipp);
 	else if (sflag)
-		procstat_cred(kipp);
+		procstat_cred(prstat, kipp);
 	else if (tflag)
-		procstat_threads(kipp);
+		procstat_threads(prstat, kipp);
 	else if (vflag)
-		procstat_vm(kipp);
+		procstat_vm(prstat, kipp);
 	else if (xflag)
-		procstat_auxv(kipp);
+		procstat_auxv(prstat, kipp);
 	else
 		procstat_basic(kipp);
 }
@@ -116,7 +116,7 @@ main(int argc, char *argv[])
 	int ch, interval, tmp;
 	int i;
 	struct kinfo_proc *p;
-	struct procstat *prstat;
+	struct procstat *prstat, *cprstat;
 	long l;
 	pid_t pid;
 	char *dummy;
@@ -255,19 +255,32 @@ main(int argc, char *argv[])
 		}
 		for (i = 0; i < argc; i++) {
 			l = strtol(argv[i], &dummy, 10);
-			if (*dummy != '\0')
-				usage();
-			if (l < 0)
-				usage();
-			pid = l;
-
-			p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt);
-			if (p == NULL)
-				errx(1, "procstat_getprocs()");
-			if (cnt != 0)
-				procstat(prstat, p);
-			procstat_freeprocs(prstat, p);
-
+			if (*dummy == '\0') {
+				if (l < 0)
+					usage();
+				pid = l;
+
+				p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt);
+				if (p == NULL)
+					errx(1, "procstat_getprocs()");
+				if (cnt != 0)
+					procstat(prstat, p);
+				procstat_freeprocs(prstat, p);
+			} else {
+				cprstat = procstat_open_core(argv[i]);
+				if (cprstat == NULL) {
+					warnx("procstat_open()");
+					continue;
+				}
+				p = procstat_getprocs(cprstat, KERN_PROC_PID,
+				    -1, &cnt);
+				if (p == NULL)
+					errx(1, "procstat_getprocs()");
+				if (cnt != 0)
+					procstat(cprstat, p);
+				procstat_freeprocs(cprstat, p);
+				procstat_close(cprstat);
+			}
 			/* Suppress header after first process. */
 			hflag = 1;
 		}

Modified: stable/9/usr.bin/procstat/procstat.h
==============================================================================
--- stable/9/usr.bin/procstat/procstat.h	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat.h	Tue May 21 19:05:27 2013	(r250871)
@@ -34,18 +34,19 @@ extern int	hflag, nflag, Cflag;
 struct kinfo_proc;
 void	kinfo_proc_sort(struct kinfo_proc *kipp, int count);
 
-void	procstat_args(struct kinfo_proc *kipp);
-void	procstat_auxv(struct kinfo_proc *kipp);
+void	procstat_args(struct procstat *prstat, struct kinfo_proc *kipp);
+void	procstat_auxv(struct procstat *prstat, struct kinfo_proc *kipp);
 void	procstat_basic(struct kinfo_proc *kipp);
-void	procstat_bin(struct kinfo_proc *kipp);
-void	procstat_cred(struct kinfo_proc *kipp);
-void	procstat_env(struct kinfo_proc *kipp);
+void	procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp);
+void	procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp);
+void	procstat_env(struct procstat *prstat, struct kinfo_proc *kipp);
 void	procstat_files(struct procstat *prstat, struct kinfo_proc *kipp);
-void	procstat_kstack(struct kinfo_proc *kipp, int kflag);
-void	procstat_rlimit(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_sigs(struct procstat *prstat, struct kinfo_proc *kipp);
-void	procstat_threads(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);
-void	procstat_vm(struct kinfo_proc *kipp);
+void	procstat_vm(struct procstat *prstat, struct kinfo_proc *kipp);
 
 #endif /* !PROCSTAT_H */

Modified: stable/9/usr.bin/procstat/procstat_args.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_args.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_args.c	Tue May 21 19:05:27 2013	(r250871)
@@ -40,52 +40,40 @@
 
 #include "procstat.h"
 
-static char args[ARG_MAX];
-
 static void
-do_args(struct kinfo_proc *kipp, int env)
+do_args(struct procstat *procstat, struct kinfo_proc *kipp, int env)
 {
-	int error, name[4];
-	size_t len;
-	char *cp;
+	int i;
+	char **args;
 
-	if (!hflag)
+	if (!hflag) {
 		printf("%5s %-16s %-53s\n", "PID", "COMM",
 		    env ? "ENVIRONMENT" : "ARGS");
-
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
-	name[3] = kipp->ki_pid;
-	len = sizeof(args);
-	error = sysctl(name, 4, args, &len, NULL, 0);
-	if (error < 0 && errno != ESRCH && errno != EPERM) {
-		warn("sysctl: kern.proc.%s: %d: %d", env ? "env" : "args",
-		    kipp->ki_pid, errno);
-		return;
 	}
-	if (error < 0)
+
+	args = env ? procstat_getenvv(procstat, kipp, 0) :
+	    procstat_getargv(procstat, kipp, 0);
+
+	printf("%5d %-16s", kipp->ki_pid, kipp->ki_comm);
+
+	if (args == NULL) {
+		printf(" -\n");
 		return;
-	if (len == 0 || strlen(args) == 0) {
-		strcpy(args, "-");
-		len = strlen(args) + 1;
 	}
 
-	printf("%5d ", kipp->ki_pid);
-	printf("%-16s ", kipp->ki_comm);
-	for (cp = args; cp < args + len; cp += strlen(cp) + 1)
-		printf("%s%s", cp != args ? " " : "", cp);
+	for (i = 0; args[i] != NULL; i++)
+		printf(" %s", args[i]);
 	printf("\n");
 }
 
 void
-procstat_args(struct kinfo_proc *kipp)
+procstat_args(struct procstat *procstat, struct kinfo_proc *kipp)
 {
-	do_args(kipp, 0);
+	do_args(procstat, kipp, 0);
 }
 
 void
-procstat_env(struct kinfo_proc *kipp)
+procstat_env(struct procstat *procstat, struct kinfo_proc *kipp)
 {
-	do_args(kipp, 1);
+	do_args(procstat, kipp, 1);
 }

Modified: stable/9/usr.bin/procstat/procstat_auxv.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_auxv.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_auxv.c	Tue May 21 19:05:27 2013	(r250871)
@@ -43,113 +43,26 @@
 
 #include "procstat.h"
 
-#define PROC_AUXV_MAX	256
-
-static Elf_Auxinfo auxv[PROC_AUXV_MAX];
-static char prefix[256];
-
-#if __ELF_WORD_SIZE == 64
-static Elf32_Auxinfo auxv32[PROC_AUXV_MAX];
-
-static const char *elf32_sv_names[] = {
-	"Linux ELF32",
-	"FreeBSD ELF32",
-};
-
-static int
-is_elf32(pid_t pid)
-{
-	int error, name[4];
-	size_t len, i;
-	static char sv_name[256];
-
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_SV_NAME;
-	name[3] = pid;
-	len = sizeof(sv_name);
-	error = sysctl(name, 4, sv_name, &len, NULL, 0);
-	if (error != 0 || len == 0)
-		return (0);
-	for (i = 0; i < sizeof(elf32_sv_names) / sizeof(*elf32_sv_names); i++) {
-		if (strncmp(sv_name, elf32_sv_names[i], sizeof(sv_name)) == 0)
-			return (1);
-	}
-	return (0);
-}
-
-static size_t
-retrieve_auxv32(pid_t pid)
-{
-	int name[4];
-	size_t len, i;
-	void *ptr;
-
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_AUXV;
-	name[3] = pid;
-	len = sizeof(auxv32);
-	if (sysctl(name, 4, auxv32, &len, NULL, 0) == -1) {
-		if (errno != ESRCH && errno != EPERM)
-			warn("sysctl: kern.proc.auxv: %d: %d", pid, errno);
-		return (0);
-	}
-	for (i = 0; i < len; i++) {
-		/*
-		 * XXX: We expect that values for a_type on a 32-bit platform
-		 * are directly mapped to those on 64-bit one, which is not
-		 * necessarily true.
-		 */
-		auxv[i].a_type = auxv32[i].a_type;
-		ptr = &auxv32[i].a_un;
-		auxv[i].a_un.a_val = *((uint32_t *)ptr);
-	}
-	return (len);
-}
-#endif /* __ELF_WORD_SIZE == 64 */
-
 #define	PRINT(name, spec, val)		\
 	printf("%s %-16s " #spec "\n", prefix, #name, (val))
 #define	PRINT_UNKNOWN(type, val)	\
 	printf("%s %16ld %#lx\n", prefix, (long)type, (u_long)(val))
 
-static size_t
-retrieve_auxv(pid_t pid)
-{
-	int name[4];
-	size_t len;
-
-#if __ELF_WORD_SIZE == 64
-	if (is_elf32(pid))
-		return (retrieve_auxv32(pid));
-#endif
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_AUXV;
-	name[3] = pid;
-	len = sizeof(auxv);
-	if (sysctl(name, 4, auxv, &len, NULL, 0) == -1) {
-		if (errno != ESRCH && errno != EPERM)
-			warn("sysctl: kern.proc.auxv: %d: %d", pid, errno);
-		return (0);
-	}
-	return (len);
-}
-
 void
-procstat_auxv(struct kinfo_proc *kipp)
+procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp)
 {
-	size_t len, i;
+	Elf_Auxinfo *auxv;
+	u_int count, i;
+	static char prefix[256];
 
 	if (!hflag)
 		printf("%5s %-16s %-16s %-16s\n", "PID", "COMM", "AUXV", "VALUE");
-	len = retrieve_auxv(kipp->ki_pid);
-	if (len == 0)
+	auxv = procstat_getauxv(procstat, kipp, &count);
+	if (auxv == NULL)
 		return;
 	snprintf(prefix, sizeof(prefix), "%5d %-16s", kipp->ki_pid,
 	    kipp->ki_comm);
-	for (i = 0; i < len; i++) {
+	for (i = 0; i < count; i++) {
 		switch(auxv[i].a_type) {
 		case AT_NULL:
 			return;
@@ -242,5 +155,6 @@ procstat_auxv(struct kinfo_proc *kipp)
 		}
 	}
 	printf("\n");
+	procstat_freeauxv(procstat, auxv);
 }
 

Modified: stable/9/usr.bin/procstat/procstat_bin.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_bin.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_bin.c	Tue May 21 19:05:27 2013	(r250871)
@@ -40,40 +40,19 @@
 #include "procstat.h"
 
 void
-procstat_bin(struct kinfo_proc *kipp)
+procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp)
 {
-	char pathname[PATH_MAX];
-	int error, osrel, name[4];
-	size_t len;
+	int osrel;
+	static char pathname[PATH_MAX];
 
 	if (!hflag)
 		printf("%5s %-16s %8s %s\n", "PID", "COMM", "OSREL", "PATH");
 
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_PATHNAME;
-	name[3] = kipp->ki_pid;
-
-	len = sizeof(pathname);
-	error = sysctl(name, 4, pathname, &len, NULL, 0);
-	if (error < 0 && errno != ESRCH) {
-		warn("sysctl: kern.proc.pathname: %d", kipp->ki_pid);
-		return;
-	}
-	if (error < 0)
+	if (procstat_getpathname(prstat, kipp, pathname, sizeof(pathname)) != 0)
 		return;
-	if (len == 0 || strlen(pathname) == 0)
+	if (strlen(pathname) == 0)
 		strcpy(pathname, "-");
-
-	name[2] = KERN_PROC_OSREL;
-
-	len = sizeof(osrel);
-	error = sysctl(name, 4, &osrel, &len, NULL, 0);
-	if (error < 0 && errno != ESRCH) {
-		warn("sysctl: kern.proc.osrel: %d", kipp->ki_pid);
-		return;
-	}
-	if (error < 0)
+	if (procstat_getosrel(prstat, kipp, &osrel) != 0)
 		return;
 
 	printf("%5d ", kipp->ki_pid);

Modified: stable/9/usr.bin/procstat/procstat_cred.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_cred.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_cred.c	Tue May 21 19:05:27 2013	(r250871)
@@ -38,16 +38,14 @@
 
 #include "procstat.h"
 
-static const char *get_umask(struct kinfo_proc *kipp);
+static const char *get_umask(struct procstat *procstat,
+    struct kinfo_proc *kipp);
 
 void
-procstat_cred(struct kinfo_proc *kipp)
+procstat_cred(struct procstat *procstat, struct kinfo_proc *kipp)
 {
-	int i;
-	int mib[4];
-	int ngroups;
-	size_t len;
-	gid_t *groups = NULL;
+	unsigned int i, ngroups;
+	gid_t *groups;
 
 	if (!hflag)
 		printf("%5s %-16s %5s %5s %5s %5s %5s %5s %5s %5s %-15s\n",
@@ -62,34 +60,18 @@ procstat_cred(struct kinfo_proc *kipp)
 	printf("%5d ", kipp->ki_groups[0]);
 	printf("%5d ", kipp->ki_rgid);
 	printf("%5d ", kipp->ki_svgid);
-	printf("%5s ", get_umask(kipp));
+	printf("%5s ", get_umask(procstat, kipp));
 	printf("%s", kipp->ki_cr_flags & CRED_FLAG_CAPMODE ? "C" : "-");
 	printf("     ");
 
+	groups = NULL;
 	/*
 	 * We may have too many groups to fit in kinfo_proc's statically
-	 * sized storage.  If that occurs, attempt to retrieve them via
-	 * sysctl.
+	 * sized storage.  If that occurs, attempt to retrieve them using
+	 * libprocstat.
 	 */
-	if (kipp->ki_cr_flags & KI_CRF_GRP_OVERFLOW) {
-		mib[0] = CTL_KERN;
-		mib[1] = KERN_PROC;
-		mib[2] = KERN_PROC_GROUPS;
-		mib[3] = kipp->ki_pid;
-
-		ngroups = sysconf(_SC_NGROUPS_MAX) + 1;
-		len = ngroups * sizeof(gid_t);
-		if((groups = malloc(len)) == NULL)
-			err(-1, "malloc");
-
-		if (sysctl(mib, 4, groups, &len, NULL, 0) == -1) {
-			warn("sysctl: kern.proc.groups: %d "
-			    "group list truncated", kipp->ki_pid);
-			free(groups);
-			groups = NULL;
-		}
-		ngroups = len / sizeof(gid_t);
-	}
+	if (kipp->ki_cr_flags & KI_CRF_GRP_OVERFLOW)
+		groups = procstat_getgroups(procstat, kipp, &ngroups);
 	if (groups == NULL) {
 		ngroups = kipp->ki_ngroups;
 		groups = kipp->ki_groups;
@@ -97,27 +79,18 @@ procstat_cred(struct kinfo_proc *kipp)
 	for (i = 0; i < ngroups; i++)
 		printf("%s%d", (i > 0) ? "," : "", groups[i]);
 	if (groups != kipp->ki_groups)
-		free(groups);
+		procstat_freegroups(procstat, groups);
 
 	printf("\n");
 }
 
 static const char *
-get_umask(struct kinfo_proc *kipp)
+get_umask(struct procstat *procstat, struct kinfo_proc *kipp)
 {
-	int error;
-	int mib[4];
-	size_t len;
 	u_short fd_cmask;
 	static char umask[4];
 
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_PROC;
-	mib[2] = KERN_PROC_UMASK;
-	mib[3] = kipp->ki_pid;
-	len = sizeof(fd_cmask);
-	error = sysctl(mib, 4, &fd_cmask, &len, NULL, 0);
-	if (error == 0) {
+	if (procstat_getumask(procstat, kipp, &fd_cmask) == 0) {
 		snprintf(umask, 4, "%03o", fd_cmask);
 		return (umask);
 	} else {

Modified: stable/9/usr.bin/procstat/procstat_kstack.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_kstack.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_kstack.c	Tue May 21 19:05:27 2013	(r250871)
@@ -125,76 +125,35 @@ kinfo_kstack_sort(struct kinfo_kstack *k
 
 
 void
-procstat_kstack(struct kinfo_proc *kipp, int kflag)
+procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag)
 {
 	struct kinfo_kstack *kkstp, *kkstp_free;
 	struct kinfo_proc *kip, *kip_free;
 	char trace[KKST_MAXLEN];
-	int error, name[4];
 	unsigned int i, j;
-	size_t kip_len, kstk_len;
+	unsigned int kip_count, kstk_count;
 
 	if (!hflag)
 		printf("%5s %6s %-16s %-16s %-29s\n", "PID", "TID", "COMM",
 		    "TDNAME", "KSTACK");
 
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_KSTACK;
-	name[3] = kipp->ki_pid;
-
-	kstk_len = 0;
-	error = sysctl(name, 4, NULL, &kstk_len, NULL, 0);
-	if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) {
-		warn("sysctl: kern.proc.kstack: %d", kipp->ki_pid);
-		return;
-	}
-	if (error < 0 && errno == ENOENT) {
-		warnx("sysctl: kern.proc.kstack unavailable");
-		errx(-1, "options DDB or options STACK required in kernel");
-	}
-	if (error < 0)
-		return;
-
-	kkstp = kkstp_free = malloc(kstk_len);
+	kkstp = kkstp_free = procstat_getkstack(procstat, kipp, &kstk_count);
 	if (kkstp == NULL)
-		err(-1, "malloc");
-
-	if (sysctl(name, 4, kkstp, &kstk_len, NULL, 0) < 0) {
-		warn("sysctl: kern.proc.pid: %d", kipp->ki_pid);
-		free(kkstp);
 		return;
-	}
 
 	/*
 	 * 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] = kipp->ki_pid;
-
-	kip_len = 0;
-	error = sysctl(name, 4, NULL, &kip_len, NULL, 0);
-	if (error < 0 && errno != ESRCH) {
-		warn("sysctl: kern.proc.pid: %d", kipp->ki_pid);
-		return;
-	}
-	if (error < 0)
-		return;
+	kip = kip_free = procstat_getprocs(procstat,
+	    KERN_PROC_PID | KERN_PROC_INC_THREAD, kipp->ki_pid, &kip_count);
 
-	kip = kip_free = malloc(kip_len);
-	if (kip == NULL)
-		err(-1, "malloc");
-
-	if (sysctl(name, 4, kip, &kip_len, NULL, 0) < 0) {
-		warn("sysctl: kern.proc.pid: %d", kipp->ki_pid);
-		free(kip);
+	if (kip == NULL) {
+		procstat_freekstack(procstat, kkstp_free);
 		return;
 	}
 
-	kinfo_kstack_sort(kkstp, kstk_len / sizeof(*kkstp));
-	for (i = 0; i < kstk_len / sizeof(*kkstp); i++) {
+	kinfo_kstack_sort(kkstp, kstk_count);
+	for (i = 0; i < kstk_count; i++) {
 		kkstp = &kkstp_free[i];
 
 		/*
@@ -202,7 +161,7 @@ procstat_kstack(struct kinfo_proc *kipp,
 		 * display the per-thread command line.
 		 */
 		kipp = NULL;
-		for (j = 0; j < kip_len / sizeof(*kipp); j++) {
+		for (j = 0; j < kip_count; j++) {
 			kipp = &kip_free[j];
 			if (kkstp->kkst_tid == kipp->ki_tid)
 				break;
@@ -242,6 +201,6 @@ procstat_kstack(struct kinfo_proc *kipp,
 		kstack_cleanup(kkstp->kkst_trace, trace, kflag);
 		printf("%-29s\n", trace);
 	}
-	free(kip_free);
-	free(kkstp_free);
+	procstat_freekstack(procstat, kkstp_free);
+	procstat_freeprocs(procstat, kip_free);
 }

Modified: stable/9/usr.bin/procstat/procstat_rlimit.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_rlimit.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_rlimit.c	Tue May 21 19:05:27 2013	(r250871)
@@ -86,31 +86,18 @@ humanize_rlimit(int indx, rlim_t limit)
 }
 
 void
-procstat_rlimit(struct kinfo_proc *kipp)
+procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp)
 {
 	struct rlimit rlimit;
-	int error, i, name[5];
-	size_t len;
+	int i;
 
 	if (!hflag) {
 		printf("%5s %-16s %-16s %16s %16s\n",
 		    "PID", "COMM", "RLIMIT", "SOFT     ", "HARD     ");
 	}
-	len = sizeof(struct rlimit);
-	name[0] = CTL_KERN;
-	name[1] = KERN_PROC;
-	name[2] = KERN_PROC_RLIMIT;
-	name[3] = kipp->ki_pid;
 	for (i = 0; i < RLIM_NLIMITS; i++) {
-		name[4] = i;
-		error = sysctl(name, 5, &rlimit, &len, NULL, 0);
-		if (error < 0 && errno != ESRCH) {
-			warn("sysctl: kern.proc.rlimit: %d", kipp->ki_pid);
+		if (procstat_getrlimit(prstat, kipp, i, &rlimit) == -1)
 			return;
-		}
-		if (error < 0 || len != sizeof(struct rlimit))
-			return;
-
 		printf("%5d %-16s %-16s ", kipp->ki_pid, kipp->ki_comm,
 		    rlimit_param[i].name);
 		printf("%16s ", humanize_rlimit(i, rlimit.rlim_cur));

Modified: stable/9/usr.bin/procstat/procstat_sigs.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_sigs.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_sigs.c	Tue May 21 19:05:27 2013	(r250871)
@@ -86,48 +86,24 @@ procstat_sigs(struct procstat *prstat __
 }
 
 void
-procstat_threads_sigs(struct procstat *prstat __unused, struct kinfo_proc *kipp)
+procstat_threads_sigs(struct procstat *procstat, struct kinfo_proc *kipp)
 {
 	struct kinfo_proc *kip;
 	pid_t pid;
-	int error, name[4], j;
-	unsigned int i;
-	size_t len;
+	int j;
+	unsigned int count, i;
 
 	pid = kipp->ki_pid;
 	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);
+	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+	    pid, &count);
 	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++) {
+	kinfo_proc_sort(kip, count);
+	for (i = 0; i < count; i++) {
 		kipp = &kip[i];
 		for (j = 1; j <= _SIG_MAXSIG; j++) {
 			printf("%5d ", pid);
@@ -140,5 +116,5 @@ procstat_threads_sigs(struct procstat *p
 			printf("\n");
 		}
 	}
-	free(kip);
+	procstat_freeprocs(procstat, kip);
 }

Modified: stable/9/usr.bin/procstat/procstat_threads.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_threads.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_threads.c	Tue May 21 19:05:27 2013	(r250871)
@@ -40,47 +40,22 @@
 #include "procstat.h"
 
 void
-procstat_threads(struct kinfo_proc *kipp)
+procstat_threads(struct procstat *procstat, struct kinfo_proc *kipp)
 {
 	struct kinfo_proc *kip;
-	int error, name[4];
-	unsigned int i;
+	unsigned int count, i;
 	const char *str;
-	size_t len;
 
 	if (!hflag)
 		printf("%5s %6s %-16s %-16s %2s %4s %-7s %-9s\n", "PID",
 		    "TID", "COMM", "TDNAME", "CPU", "PRI", "STATE", "WCHAN");
 
-	/*
-	 * 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] = kipp->ki_pid;
-
-	len = 0;
-	error = sysctl(name, 4, NULL, &len, NULL, 0);
-	if (error < 0 && errno != ESRCH) {
-		warn("sysctl: kern.proc.pid: %d", kipp->ki_pid);
-		return;
-	}
-	if (error < 0)
-		return;
-
-	kip = malloc(len);
+	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+	    kipp->ki_pid, &count);
 	if (kip == NULL)
-		err(-1, "malloc");
-
-	if (sysctl(name, 4, kip, &len, NULL, 0) < 0) {
-		warn("sysctl: kern.proc.pid: %d", kipp->ki_pid);
-		free(kip);
 		return;
-	}
-
-	kinfo_proc_sort(kip, len / sizeof(*kipp));
-	for (i = 0; i < len / sizeof(*kipp); i++) {
+	kinfo_proc_sort(kip, count);
+	for (i = 0; i < count; i++) {
 		kipp = &kip[i];
 		printf("%5d ", kipp->ki_pid);
 		printf("%6d ", kipp->ki_tid);
@@ -139,5 +114,5 @@ procstat_threads(struct kinfo_proc *kipp
 		}
 		printf("\n");
 	}
-	free(kip);
+	procstat_freeprocs(procstat, kip);
 }

Modified: stable/9/usr.bin/procstat/procstat_vm.c
==============================================================================
--- stable/9/usr.bin/procstat/procstat_vm.c	Tue May 21 19:04:16 2013	(r250870)
+++ stable/9/usr.bin/procstat/procstat_vm.c	Tue May 21 19:05:27 2013	(r250871)
@@ -41,7 +41,7 @@
 #include "procstat.h"
 
 void
-procstat_vm(struct kinfo_proc *kipp)
+procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
 {
 	struct kinfo_vmentry *freep, *kve;
 	int ptrwidth;
@@ -54,7 +54,7 @@ procstat_vm(struct kinfo_proc *kipp)
 		    "PID", ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
 		    "PRES", "REF", "SHD", "FL", "TP", "PATH");
 
-	freep = kinfo_getvmmap(kipp->ki_pid, &cnt);
+	freep = procstat_getvmmap(procstat, kipp, &cnt);
 	if (freep == NULL)
 		return;
 	for (i = 0; i < cnt; i++) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305211905.r4LJ5SU6016158>