summaryrefslogtreecommitdiffstats
path: root/usr.bin/procstat
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2007-12-03 21:21:15 +0000
committerrwatson <rwatson@FreeBSD.org>2007-12-03 21:21:15 +0000
commit6d8cbbd3e81479009deff9e2b5aff6c731225a92 (patch)
treebcacf317381c82efea001ac774a2f3be8b4a4afe /usr.bin/procstat
parent33c8c2ef9f896225425077f937727fa0e3372aac (diff)
downloadFreeBSD-src-6d8cbbd3e81479009deff9e2b5aff6c731225a92.zip
FreeBSD-src-6d8cbbd3e81479009deff9e2b5aff6c731225a92.tar.gz
Display per-thread command line in TDNAME field for -k and -t; if
no per-thread name is available or the name is identical to the process name, display "-" instead. Very slightly shrink the COMM entry to make a bit more room, although this doesn't help with stack traces much. Suggested by: thompsa
Diffstat (limited to 'usr.bin/procstat')
-rw-r--r--usr.bin/procstat/procstat_kstack.c83
-rw-r--r--usr.bin/procstat/procstat_threads.c9
2 files changed, 71 insertions, 21 deletions
diff --git a/usr.bin/procstat/procstat_kstack.c b/usr.bin/procstat/procstat_kstack.c
index c36720a..c152388 100644
--- a/usr.bin/procstat/procstat_kstack.c
+++ b/usr.bin/procstat/procstat_kstack.c
@@ -127,62 +127,108 @@ void
procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag)
{
struct kinfo_kstack *kkstp, *kkstp_free;
+ struct kinfo_proc *kip, *kip_free;
char trace[KKST_MAXLEN];
- int error, i, name[4];
- size_t len;
+ int error, i, j, name[4];
+ size_t kip_len, kstk_len;
if (!hflag)
- printf("%5s %6s %-20s %-45s\n", "PID", "TID", "COMM",
- "KSTACK");
+ 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] = pid;
- len = 0;
- error = sysctl(name, 4, NULL, &len, NULL, 0);
+ 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", pid);
return;
}
- if (error < 0 && errno == ENOENT)
- errx(-1, "kern.proc.kstack sysctl unavailable; options DDB "
- "is required.");
+ 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(len);
+ kkstp = kkstp_free = malloc(kstk_len);
if (kkstp == NULL)
err(-1, "malloc");
- if (sysctl(name, 4, kkstp, &len, NULL, 0) < 0) {
+ if (sysctl(name, 4, kkstp, &kstk_len, NULL, 0) < 0) {
warn("sysctl: kern.proc.pid: %d", pid);
free(kkstp);
return;
}
- kinfo_kstack_sort(kkstp, len / sizeof(*kkstp));
- for (i = 0; i < len / sizeof(*kkstp); i++) {
+ /*
+ * 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;
+
+ kip_len = 0;
+ error = sysctl(name, 4, NULL, &kip_len, NULL, 0);
+ if (error < 0 && errno != ESRCH) {
+ warn("sysctl: kern.proc.pid: %d", pid);
+ return;
+ }
+ if (error < 0)
+ return;
+
+ 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", pid);
+ free(kip);
+ return;
+ }
+
+ kinfo_kstack_sort(kkstp, kstk_len / sizeof(*kkstp));
+ for (i = 0; i < kstk_len / sizeof(*kkstp); i++) {
kkstp = &kkstp_free[i];
+
+ /*
+ * Look up the specific thread using its tid so we can
+ * display the per-thread command line.
+ */
+ kipp = NULL;
+ for (j = 0; j < kip_len / sizeof(*kipp); j++) {
+ kipp = &kip_free[j];
+ if (kkstp->kkst_tid == kipp->ki_tid)
+ break;
+ }
+ if (kipp == NULL)
+ continue;
+
printf("%5d ", pid);
printf("%6d ", kkstp->kkst_tid);
- printf("%-20s ", kipp->ki_comm);
+ printf("%-16s ", kipp->ki_comm);
+ printf("%-16s ", (strlen(kipp->ki_ocomm) &&
+ (strcmp(kipp->ki_comm, kipp->ki_ocomm) != 0)) ?
+ kipp->ki_ocomm : "-");
switch (kkstp->kkst_state) {
case KKST_STATE_RUNNING:
- printf("%-45s\n", "<running>");
+ printf("%-29s\n", "<running>");
continue;
case KKST_STATE_SWAPPED:
- printf("%-45s\n", "<swapped>");
+ printf("%-29s\n", "<swapped>");
continue;
case KKST_STATE_STACKOK:
break;
default:
- printf("%-45s\n", "<unknown>");
+ printf("%-29s\n", "<unknown>");
continue;
}
@@ -192,7 +238,8 @@ procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag)
* returns to spaces.
*/
kstack_cleanup(kkstp->kkst_trace, trace, kflag);
- printf("%-45s\n", trace);
+ printf("%-29s\n", trace);
}
+ free(kip_free);
free(kkstp_free);
}
diff --git a/usr.bin/procstat/procstat_threads.c b/usr.bin/procstat/procstat_threads.c
index dbfde79..a1cd6e5 100644
--- a/usr.bin/procstat/procstat_threads.c
+++ b/usr.bin/procstat/procstat_threads.c
@@ -47,8 +47,8 @@ procstat_threads(pid_t pid, struct kinfo_proc *kipp)
size_t len;
if (!hflag)
- printf("%5s %6s %-20s %2s %4s %-7s %-9s\n", "PID", "TID",
- "COMM", "CPU", "PRI", "STATE", "WCHAN");
+ 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.
@@ -82,8 +82,11 @@ procstat_threads(pid_t pid, struct kinfo_proc *kipp)
kipp = &kip[i];
printf("%5d ", pid);
printf("%6d ", kipp->ki_tid);
- printf("%-20s ", strlen(kipp->ki_comm) ?
+ printf("%-16s ", strlen(kipp->ki_comm) ?
kipp->ki_comm : "-");
+ printf("%-16s ", (strlen(kipp->ki_ocomm) &&
+ (strcmp(kipp->ki_comm, kipp->ki_ocomm) != 0)) ?
+ kipp->ki_ocomm : "-");
if (kipp->ki_oncpu != 255)
printf("%3d ", kipp->ki_oncpu);
else if (kipp->ki_lastcpu != 255)
OpenPOWER on IntegriCloud