Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Apr 2013 08:19:06 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r249685 - head/usr.bin/procstat
Message-ID:  <201304200819.r3K8J67M022794@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Sat Apr 20 08:19:06 2013
New Revision: 249685
URL: http://svnweb.freebsd.org/changeset/base/249685

Log:
  Use procstat_getkstack(3) for retrieving process kernel stacks
  instead of direct sysctl calls.
  
  MFC after:	1 month

Modified:
  head/usr.bin/procstat/procstat.c
  head/usr.bin/procstat/procstat.h
  head/usr.bin/procstat/procstat_kstack.c

Modified: head/usr.bin/procstat/procstat.c
==============================================================================
--- head/usr.bin/procstat/procstat.c	Sat Apr 20 08:17:20 2013	(r249684)
+++ head/usr.bin/procstat/procstat.c	Sat Apr 20 08:19:06 2013	(r249685)
@@ -71,7 +71,7 @@ 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(prstat, kipp);
 	else if (sflag)

Modified: head/usr.bin/procstat/procstat.h
==============================================================================
--- head/usr.bin/procstat/procstat.h	Sat Apr 20 08:17:20 2013	(r249684)
+++ head/usr.bin/procstat/procstat.h	Sat Apr 20 08:19:06 2013	(r249685)
@@ -41,7 +41,8 @@ void	procstat_bin(struct procstat *prsta
 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_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 procstat *prstat, struct kinfo_proc *kipp);

Modified: head/usr.bin/procstat/procstat_kstack.c
==============================================================================
--- head/usr.bin/procstat/procstat_kstack.c	Sat Apr 20 08:17:20 2013	(r249684)
+++ head/usr.bin/procstat/procstat_kstack.c	Sat Apr 20 08:19:06 2013	(r249685)
@@ -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);
 }



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