Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Dec 2012 20:40:55 -0600
From:      Mike Karels <mike_karels@mcafee.com>
To:        <FreeBSD-gnats-submit@FreeBSD.org>
Subject:   bin/174848: ps -H option does not work with kernel core dumps
Message-ID:  <201212310240.qBV2etsI050887@mcafee.com>
Resent-Message-ID: <201212310250.qBV2o0Ml047274@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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:



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