Index: lib/libkvm/kvm_proc.c =================================================================== --- lib/libkvm/kvm_proc.c +++ lib/libkvm/kvm_proc.c @@ -130,30 +130,37 @@ 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); return (-1); } if (proc.p_state == PRS_NEW) - continue; + goto next; + 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; @@ -183,27 +190,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; } /* @@ -222,6 +229,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; @@ -352,18 +360,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) @@ -385,6 +393,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; @@ -453,6 +462,9 @@ bcopy(&kinfo_proc, bp, sizeof(kinfo_proc)); ++bp; ++cnt; +next: + if (td == NULL) + p = LIST_NEXT(&proc, p_list); } return (cnt); } @@ -595,6 +607,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);