bin/174848: ps -H option does not work with kernel core dumps
Mike Karels
mike_karels at mcafee.com
Mon Dec 31 02:50:01 UTC 2012
>Number: 174848
>Category: bin
>Synopsis: ps -H option does not work with kernel core dumps
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Dec 31 02:50:00 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Mike Karels
>Release: FreeBSD 10.0-CURRENT amd64
>Organization:
McAfee, Inc
>Environment:
System: FreeBSD freebsd-current.karels.net 10.0-CURRENT FreeBSD 10.0-CURRENT #1 r244048: Sun Dec 9 18:48:31 UTC 2012 root at snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
The ps -H option does not display kernel threads, which is mostly a
problem in libkvm. It also does not display kernel thread names,
even with -c. The attached patches to libkvm/kvm_proc.c and the ps
program fix both, and add a more-intuitive "tid" keyword (vs "lwp").
This has been a problem since about 8.0.
>How-To-Repeat:
ps -axlwwHc -o tid -M vmcore.0
>Fix:
Index: kvm_proc.c
===================================================================
--- kvm_proc.c (revision 244594)
+++ kvm_proc.c (working copy)
@@ -131,14 +131,16 @@
struct proc pproc;
struct sysentvec sysent;
char svname[KI_EMULNAMELEN];
+ struct thread *td = NULL;
kp = &kinfo_proc;
kp->ki_structsize = sizeof(kinfo_proc);
/*
- * Loop on the processes. this is completely broken because we need to be
- * able to loop on the threads and merge the ones that are the same process some how.
+ * Loop on the processes, then threads within the process if requested.
*/
- for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) {
+ if (what == KERN_PROC_ALL)
+ what |= KERN_PROC_INC_THREAD;
+ for (; cnt < maxcnt && p != NULL; ) {
memset(kp, 0, sizeof *kp);
if (KREAD(kd, (u_long)p, &proc)) {
_kvm_err(kd, kd->program, "can't read proc at %p", p);
@@ -146,15 +148,20 @@
}
if (proc.p_state == PRS_NEW)
continue;
+ if (td == NULL)
+ td = TAILQ_FIRST(&proc.p_threads);
if (proc.p_state != PRS_ZOMBIE) {
- if (KREAD(kd, (u_long)TAILQ_FIRST(&proc.p_threads),
- &mtd)) {
+ if (KREAD(kd, (u_long)td, &mtd)) {
_kvm_err(kd, kd->program,
- "can't read thread at %p",
- TAILQ_FIRST(&proc.p_threads));
+ "can't read thread at %p", td);
return (-1);
}
- }
+ if (what & KERN_PROC_INC_THREAD)
+ td = TAILQ_NEXT(&mtd, td_plist);
+ else
+ td = NULL;
+ } else
+ td = NULL;
if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) {
kp->ki_ruid = ucred.cr_ruid;
kp->ki_svuid = ucred.cr_svuid;
@@ -184,27 +191,27 @@
case KERN_PROC_GID:
if (kp->ki_groups[0] != (gid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_PID:
if (proc.p_pid != (pid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_RGID:
if (kp->ki_rgid != (gid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_UID:
if (kp->ki_uid != (uid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_RUID:
if (kp->ki_ruid != (uid_t)arg)
- continue;
+ goto next;
break;
}
/*
@@ -223,6 +230,7 @@
kp->ki_addr = 0; /* XXX uarea */
/* kp->ki_kstack = proc.p_thread.td_kstack; XXXKSE */
kp->ki_args = proc.p_args;
+ kp->ki_numthreads = proc.p_numthreads;
kp->ki_tracep = proc.p_tracevp;
kp->ki_textvp = proc.p_textvp;
kp->ki_fd = proc.p_fd;
@@ -353,18 +361,18 @@
case KERN_PROC_PGRP:
if (kp->ki_pgid != (pid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_SESSION:
if (kp->ki_sid != (pid_t)arg)
- continue;
+ goto next;
break;
case KERN_PROC_TTY:
if ((proc.p_flag & P_CONTROLT) == 0 ||
kp->ki_tdev != (dev_t)arg)
- continue;
+ goto next;
break;
}
if (proc.p_comm[0] != 0)
@@ -386,6 +394,7 @@
}
kp->ki_runtime = cputick2usec(proc.p_rux.rux_runtime);
kp->ki_pid = proc.p_pid;
+ kp->ki_tid = mtd.td_tid;
kp->ki_siglist = proc.p_siglist;
SIGSETOR(kp->ki_siglist, mtd.td_siglist);
kp->ki_sigmask = mtd.td_sigmask;
@@ -424,8 +433,6 @@
kp->ki_pri.pri_native = mtd.td_base_pri;
kp->ki_lastcpu = mtd.td_lastcpu;
kp->ki_wchan = mtd.td_wchan;
- if (mtd.td_name[0] != 0)
- strlcpy(kp->ki_tdname, mtd.td_name, MAXCOMLEN);
kp->ki_oncpu = mtd.td_oncpu;
if (mtd.td_name[0] != '\0')
strlcpy(kp->ki_tdname, mtd.td_name, sizeof(kp->ki_tdname));
@@ -437,6 +444,9 @@
bcopy(&kinfo_proc, bp, sizeof(kinfo_proc));
++bp;
++cnt;
+next:
+ if (td == NULL)
+ p = LIST_NEXT(&proc, p_list);
}
return (cnt);
}
@@ -573,6 +583,8 @@
_kvm_err(kd, kd->program, "can't read nprocs");
return (0);
}
+ if (op == KERN_PROC_ALL || (op & KERN_PROC_INC_THREAD))
+ nprocs *= 10; /* XXX */
if (KREAD(kd, nl[3].n_value, &ticks)) {
_kvm_err(kd, kd->program, "can't read ticks");
return (0);
Index: ps.1
===================================================================
--- ps.1 (revision 244594)
+++ ps.1 (working copy)
@@ -629,6 +629,8 @@
thread address
.It Cm tdev
control terminal device number
+.It Cm tid
+thread ID, same as lwp
.It Cm time
accumulated CPU time, user + system (alias
.Cm cputime )
Index: keyword.c
===================================================================
--- keyword.c (revision 244594)
+++ keyword.c (working copy)
@@ -152,6 +152,7 @@
{"tdaddr", "TDADDR", NULL, 0, kvar, KOFF(ki_tdaddr), KPTR, "lx", 0},
{"tdev", "TDEV", NULL, 0, tdev, 0, CHAR, NULL, 0},
{"tdnam", "TDNAM", NULL, LJUST, tdnam, 0, CHAR, NULL, 0},
+ {"tid", "TID", NULL, 0, kvar, KOFF(ki_tid), UINT, LWPFMT, 0},
{"time", "TIME", NULL, USER, cputime, 0, CHAR, NULL, 0},
{"tpgid", "TPGID", NULL, 0, kvar, KOFF(ki_tpgid), UINT, PIDFMT, 0},
{"tsid", "TSID", NULL, 0, kvar, KOFF(ki_tsid), UINT, PIDFMT, 0},
Index: print.c
===================================================================
--- print.c (revision 244594)
+++ print.c (working copy)
@@ -124,7 +124,9 @@
k->ki_p->ki_comm,
(showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "",
(showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : "");
- } else
+ } else if (showthreads && k->ki_p->ki_numthreads > 1)
+ asprintf(&str, "%s/%s", k->ki_p->ki_comm, k->ki_p->ki_tdname);
+ else
str = strdup(k->ki_p->ki_comm);
return (str);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list