>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     
r...@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to