/* * Build proc info array by reading in proc list from a crash dump. * We reallocate kd->procbase as necessary. */ static int kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc, u_long a_zombproc) { struct kinfo_proc *bp = kd->procbase; int acnt, zcnt; struct proc *p; if (KREAD(kd, a_allproc, &p)) { _kvm_err(kd, kd->program, "cannot read allproc"); return (-1); } acnt = kvm_proclist(kd, what, arg, p, bp); if (acnt < 0) return (acnt); 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); if (zcnt < 0) zcnt = 0; return (acnt + zcnt); }
/* * Build proc info array by reading in proc list from a crash dump. * We reallocate kd->procbase as necessary. */ static int kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc, int allproc_hsize) { struct kinfo_proc *bp; struct proc *p; struct proclist **pl; int cnt, partcnt, n; u_long nextoff; cnt = partcnt = 0; nextoff = 0; /* * Dynamically allocate space for all the elements of the * allprocs array and KREAD() them. */ pl = _kvm_malloc(kd, allproc_hsize * sizeof(struct proclist *)); for (n = 0; n < allproc_hsize; n++) { pl[n] = _kvm_malloc(kd, sizeof(struct proclist)); nextoff = a_allproc + (n * sizeof(struct proclist)); if (KREAD(kd, (u_long)nextoff, pl[n])) { _kvm_err(kd, kd->program, "can't read proclist at 0x%lx", a_allproc); return (-1); } /* Ignore empty proclists */ if (LIST_EMPTY(pl[n])) continue; bp = kd->procbase + cnt; p = pl[n]->lh_first; partcnt = kvm_proclist(kd, what, arg, p, bp); if (partcnt < 0) { free(pl[n]); return (partcnt); } cnt += partcnt; free(pl[n]); } return (cnt); }
struct kinfo_proc * kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt) { int mib[6], st, nthreads; size_t size; if ((ssize_t)esize < 0) return (NULL); if (kd->procbase != NULL) { free(kd->procbase); /* * Clear this pointer in case this call fails. Otherwise, * kvm_close() will free it again. */ kd->procbase = 0; } if (ISALIVE(kd)) { size = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = op; mib[3] = arg; mib[4] = esize; mib[5] = 0; st = sysctl(mib, 6, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (NULL); } mib[5] = size / esize; kd->procbase = _kvm_malloc(kd, size); if (kd->procbase == 0) return (NULL); st = sysctl(mib, 6, kd->procbase, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (NULL); } nthreads = size / esize; } else { struct nlist nl[4]; int i, maxthread; struct proc *p; char *bp; if (esize > sizeof(struct kinfo_proc)) { _kvm_syserr(kd, kd->program, "kvm_getprocs: unknown fields requested: libkvm out of date?"); return (NULL); } memset(nl, 0, sizeof(nl)); nl[0].n_name = "_nthreads"; nl[1].n_name = "_allproc"; nl[2].n_name = "_zombproc"; nl[3].n_name = NULL; if (kvm_nlist(kd, nl) != 0) { for (i = 0; nl[i].n_type != 0; ++i) ; _kvm_err(kd, kd->program, "%s: no such symbol", nl[i].n_name); return (NULL); } if (KREAD(kd, nl[0].n_value, &maxthread)) { _kvm_err(kd, kd->program, "can't read nthreads"); return (NULL); } kd->procbase = _kvm_malloc(kd, maxthread * esize); if (kd->procbase == 0) return (NULL); bp = (char *)kd->procbase; /* allproc */ if (KREAD(kd, nl[1].n_value, &p)) { _kvm_err(kd, kd->program, "cannot read allproc"); return (NULL); } nthreads = kvm_proclist(kd, op, arg, p, bp, maxthread, esize); if (nthreads < 0) return (NULL); /* zombproc */ if (KREAD(kd, nl[2].n_value, &p)) { _kvm_err(kd, kd->program, "cannot read zombproc"); return (NULL); } i = kvm_proclist(kd, op, arg, p, bp + (esize * nthreads), maxthread - nthreads, esize); if (i > 0) nthreads += i; } if (kd->procbase != NULL) *cnt = nthreads; return (kd->procbase); }