summaryrefslogtreecommitdiffstats
path: root/usr.bin/procstat
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2013-04-20 08:19:06 +0000
committertrociny <trociny@FreeBSD.org>2013-04-20 08:19:06 +0000
commite79062469fbe0c97917c049158d1ee16f1fd23f3 (patch)
treed48af5680e4fd9e9c3e67813890a2f13a6b76a5f /usr.bin/procstat
parent457eff386468328043f16986ad34521af9ffafc7 (diff)
downloadFreeBSD-src-e79062469fbe0c97917c049158d1ee16f1fd23f3.zip
FreeBSD-src-e79062469fbe0c97917c049158d1ee16f1fd23f3.tar.gz
Use procstat_getkstack(3) for retrieving process kernel stacks
instead of direct sysctl calls. MFC after: 1 month
Diffstat (limited to 'usr.bin/procstat')
-rw-r--r--usr.bin/procstat/procstat.c2
-rw-r--r--usr.bin/procstat/procstat.h3
-rw-r--r--usr.bin/procstat/procstat_kstack.c65
3 files changed, 15 insertions, 55 deletions
diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c
index 1e28341..366c8f1f 100644
--- a/usr.bin/procstat/procstat.c
+++ b/usr.bin/procstat/procstat.c
@@ -71,7 +71,7 @@ procstat(struct procstat *prstat, struct kinfo_proc *kipp)
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)
diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h
index a0ec2e5d..57c9cb5 100644
--- a/usr.bin/procstat/procstat.h
+++ b/usr.bin/procstat/procstat.h
@@ -41,7 +41,8 @@ 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_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);
diff --git a/usr.bin/procstat/procstat_kstack.c b/usr.bin/procstat/procstat_kstack.c
index d887262..8ffa4f9 100644
--- a/usr.bin/procstat/procstat_kstack.c
+++ b/usr.bin/procstat/procstat_kstack.c
@@ -125,76 +125,35 @@ kinfo_kstack_sort(struct kinfo_kstack *kkstp, int count)
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 = malloc(kip_len);
- if (kip == NULL)
- err(-1, "malloc");
+ kip = kip_free = procstat_getprocs(procstat,
+ KERN_PROC_PID | KERN_PROC_INC_THREAD, kipp->ki_pid, &kip_count);
- 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, int kflag)
* 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, int kflag)
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);
}
OpenPOWER on IntegriCloud