Subject: Re: lib/20915: ps won't work against dead current kernels, libkvm out of date
To: <>
From: David Laight <david@l8s.co.uk>
List: netbsd-bugs
Date: 04/06/2003 00:13:24
> nm /netbsd | grep deadproc says that it's now deadprocs, so i changed
> libkvm to look for that instead and then ps gave me output.  i think
> that's probably very wrong, though (the change, not the output), so i
> changed it back and filed this pr.

This code from kvm_deadprocs in libkvm/kvm_proc.c is highly dubious!
(I've removed the error reporting for brevity)

	if (KREAD(kd, a_allproc, &p)) ...
	acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);

	if (KREAD(kd, a_deadproc, &p)) ...
	dcnt = kvm_proclist(kd, what, arg, p, bp, maxcnt - acnt);

	if (KREAD(kd, a_zombproc, &p)) ...
	zcnt = kvm_proclist(kd, what, arg, p, bp + acnt,
	    maxcnt - (acnt + dcnt));

	return (acnt + zcnt);

If there were ever anything on 'deadproc' the info would overwrite
the first (few) normal processes.  Looks to me like some code merge
failed when (I guess) 'dead' processes were always on the zombproc list.

This should fix it:

Index: kvm_proc.c
===================================================================
RCS file: /cvsroot/src/lib/libkvm/kvm_proc.c,v
retrieving revision 1.51
diff -u -p -r1.51 kvm_proc.c
--- kvm_proc.c	2003/03/19 11:36:34	1.51
+++ kvm_proc.c	2003/04/05 23:14:47
@@ -170,8 +170,7 @@ static ssize_t	kvm_ureadm __P((kvm_t *, 
 
 static char	**kvm_argv __P((kvm_t *, const struct miniproc *, u_long, int,
 		    int));
-static int	kvm_deadprocs __P((kvm_t *, int, int, u_long, u_long, u_long,
-		    int));
+static int	kvm_deadprocs __P((kvm_t *, int, int, u_long, u_long, int));
 static char	**kvm_doargv __P((kvm_t *, const struct miniproc *, int,
 		    void (*)(struct ps_strings *, u_long *, int *)));
 static char	**kvm_doargv2 __P((kvm_t *, pid_t, int, int));
@@ -426,16 +425,15 @@ kvm_proclist(kd, what, arg, p, bp, maxcn
  * Return number of procs read.  maxcnt is the max we will read.
  */
 static int
-kvm_deadprocs(kd, what, arg, a_allproc, a_deadproc, a_zombproc, maxcnt)
+kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt)
 	kvm_t *kd;
 	int what, arg;
 	u_long a_allproc;
-	u_long a_deadproc;
 	u_long a_zombproc;
 	int maxcnt;
 {
 	struct kinfo_proc *bp = kd->procbase;
-	int acnt, dcnt, zcnt;
+	int acnt, zcnt;
 	struct proc *p;
 
 	if (KREAD(kd, a_allproc, &p)) {
@@ -446,21 +444,11 @@ kvm_deadprocs(kd, what, arg, a_allproc, 
 	if (acnt < 0)
 		return (acnt);
 
-	if (KREAD(kd, a_deadproc, &p)) {
-		_kvm_err(kd, kd->program, "cannot read deadproc");
-		return (-1);
-	}
-
-	dcnt = kvm_proclist(kd, what, arg, p, bp, maxcnt - acnt);
-	if (dcnt < 0)
-		dcnt = 0;
-
 	if (KREAD(kd, a_zombproc, &p)) {
 		_kvm_err(kd, kd->program, "cannot read zombproc");
 		return (-1);
 	}
-	zcnt = kvm_proclist(kd, what, arg, p, bp + acnt,
-	    maxcnt - (acnt + dcnt));
+	zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
 	if (zcnt < 0)
 		zcnt = 0;
 
@@ -839,13 +827,12 @@ kvm_getprocs(kd, op, arg, cnt)
 		    "can't use kvm_getprocs");
 		return (NULL);
 	} else {
-		struct nlist nl[5], *p;
+		struct nlist nl[4], *p;
 
 		nl[0].n_name = "_nprocs";
 		nl[1].n_name = "_allproc";
-		nl[2].n_name = "_deadproc";
-		nl[3].n_name = "_zombproc";
-		nl[4].n_name = NULL;
+		nl[2].n_name = "_zombproc";
+		nl[3].n_name = NULL;
 
 		if (kvm_nlist(kd, nl) != 0) {
 			for (p = nl; p->n_type != 0; ++p)
@@ -864,7 +851,7 @@ kvm_getprocs(kd, op, arg, cnt)
 			return (NULL);
 
 		nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
-		    nl[2].n_value, nl[3].n_value, nprocs);
+		    nl[2].n_value, nprocs);
 		if (nprocs < 0)
 			return (NULL);
 #ifdef notdef

	David

-- 
David Laight: david@l8s.co.uk