Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libkvm/kvm_proc.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <sys/tty.h> | #include <sys/tty.h> | ||||
#include <sys/file.h> | #include <sys/file.h> | ||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#define _WANT_KW_EXITCODE | #define _WANT_KW_EXITCODE | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdbool.h> | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <nlist.h> | #include <nlist.h> | ||||
#include <kvm.h> | #include <kvm.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <memory.h> | #include <memory.h> | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
struct ucred ucred; | struct ucred ucred; | ||||
struct prison pr; | struct prison pr; | ||||
struct thread mtd; | struct thread mtd; | ||||
struct proc proc; | struct proc proc; | ||||
struct proc pproc; | struct proc pproc; | ||||
struct sysentvec sysent; | struct sysentvec sysent; | ||||
char svname[KI_EMULNAMELEN]; | char svname[KI_EMULNAMELEN]; | ||||
struct thread *td = NULL; | |||||
bool first_thread; | |||||
kp = &kinfo_proc; | kp = &kinfo_proc; | ||||
kp->ki_structsize = sizeof(kinfo_proc); | kp->ki_structsize = sizeof(kinfo_proc); | ||||
/* | /* | ||||
* Loop on the processes. this is completely broken because we need to be | * Loop on the processes, then threads within the process if requested. | ||||
* able to loop on the threads and merge the ones that are the same process some how. | |||||
*/ | */ | ||||
if (what == KERN_PROC_ALL) | |||||
what |= KERN_PROC_INC_THREAD; | |||||
for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) { | for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) { | ||||
memset(kp, 0, sizeof *kp); | memset(kp, 0, sizeof *kp); | ||||
if (KREAD(kd, (u_long)p, &proc)) { | if (KREAD(kd, (u_long)p, &proc)) { | ||||
_kvm_err(kd, kd->program, "can't read proc at %p", p); | _kvm_err(kd, kd->program, "can't read proc at %p", p); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (proc.p_state == PRS_NEW) | if (proc.p_state == PRS_NEW) | ||||
continue; | continue; | ||||
if (proc.p_state != PRS_ZOMBIE) { | |||||
if (KREAD(kd, (u_long)TAILQ_FIRST(&proc.p_threads), | |||||
&mtd)) { | |||||
_kvm_err(kd, kd->program, | |||||
"can't read thread at %p", | |||||
TAILQ_FIRST(&proc.p_threads)); | |||||
return (-1); | |||||
} | |||||
} | |||||
if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) { | if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) { | ||||
kp->ki_ruid = ucred.cr_ruid; | kp->ki_ruid = ucred.cr_ruid; | ||||
kp->ki_svuid = ucred.cr_svuid; | kp->ki_svuid = ucred.cr_svuid; | ||||
kp->ki_rgid = ucred.cr_rgid; | kp->ki_rgid = ucred.cr_rgid; | ||||
kp->ki_svgid = ucred.cr_svgid; | kp->ki_svgid = ucred.cr_svgid; | ||||
kp->ki_cr_flags = ucred.cr_flags; | kp->ki_cr_flags = ucred.cr_flags; | ||||
if (ucred.cr_ngroups > KI_NGROUPS) { | if (ucred.cr_ngroups > KI_NGROUPS) { | ||||
kp->ki_ngroups = KI_NGROUPS; | kp->ki_ngroups = KI_NGROUPS; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) { | ||||
} | } | ||||
/* | /* | ||||
* gather kinfo_proc | * gather kinfo_proc | ||||
*/ | */ | ||||
kp->ki_paddr = p; | kp->ki_paddr = p; | ||||
kp->ki_addr = 0; /* XXX uarea */ | kp->ki_addr = 0; /* XXX uarea */ | ||||
/* kp->ki_kstack = proc.p_thread.td_kstack; XXXKSE */ | /* kp->ki_kstack = proc.p_thread.td_kstack; XXXKSE */ | ||||
kp->ki_args = proc.p_args; | kp->ki_args = proc.p_args; | ||||
kp->ki_numthreads = proc.p_numthreads; | |||||
kp->ki_tracep = proc.p_tracevp; | kp->ki_tracep = proc.p_tracevp; | ||||
kp->ki_textvp = proc.p_textvp; | kp->ki_textvp = proc.p_textvp; | ||||
kp->ki_fd = proc.p_fd; | kp->ki_fd = proc.p_fd; | ||||
kp->ki_vmspace = proc.p_vmspace; | kp->ki_vmspace = proc.p_vmspace; | ||||
if (proc.p_sigacts != NULL) { | if (proc.p_sigacts != NULL) { | ||||
if (KREAD(kd, (u_long)proc.p_sigacts, &sigacts)) { | if (KREAD(kd, (u_long)proc.p_sigacts, &sigacts)) { | ||||
_kvm_err(kd, kd->program, | _kvm_err(kd, kd->program, | ||||
"can't read sigacts at %p", proc.p_sigacts); | "can't read sigacts at %p", proc.p_sigacts); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | #endif | ||||
if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) { | if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) { | ||||
_kvm_err(kd, kd->program, "can't read session at %p", | _kvm_err(kd, kd->program, "can't read session at %p", | ||||
pgrp.pg_session); | pgrp.pg_session); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
kp->ki_sid = sess.s_sid; | kp->ki_sid = sess.s_sid; | ||||
(void)memcpy(kp->ki_login, sess.s_login, | (void)memcpy(kp->ki_login, sess.s_login, | ||||
sizeof(kp->ki_login)); | sizeof(kp->ki_login)); | ||||
kp->ki_kiflag = sess.s_ttyvp ? KI_CTTY : 0; | |||||
if (sess.s_leader == p) | |||||
kp->ki_kiflag |= KI_SLEADER; | |||||
if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) { | if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) { | ||||
if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) { | if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) { | ||||
_kvm_err(kd, kd->program, | _kvm_err(kd, kd->program, | ||||
"can't read tty at %p", sess.s_ttyp); | "can't read tty at %p", sess.s_ttyp); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (tty.t_dev != NULL) { | if (tty.t_dev != NULL) { | ||||
if (KREAD(kd, (u_long)tty.t_dev, &t_cdev)) { | if (KREAD(kd, (u_long)tty.t_dev, &t_cdev)) { | ||||
Show All 26 Lines | #endif | ||||
return (-1); | return (-1); | ||||
} | } | ||||
kp->ki_tsid = sess.s_sid; | kp->ki_tsid = sess.s_sid; | ||||
} | } | ||||
} else { | } else { | ||||
nopgrp: | nopgrp: | ||||
kp->ki_tdev = NODEV; | kp->ki_tdev = NODEV; | ||||
} | } | ||||
if ((proc.p_state != PRS_ZOMBIE) && mtd.td_wmesg) | |||||
(void)kvm_read(kd, (u_long)mtd.td_wmesg, | |||||
kp->ki_wmesg, WMESGLEN); | |||||
(void)kvm_read(kd, (u_long)proc.p_vmspace, | (void)kvm_read(kd, (u_long)proc.p_vmspace, | ||||
(char *)&vmspace, sizeof(vmspace)); | (char *)&vmspace, sizeof(vmspace)); | ||||
kp->ki_size = vmspace.vm_map.size; | kp->ki_size = vmspace.vm_map.size; | ||||
/* | /* | ||||
* Approximate the kernel's method of calculating | * Approximate the kernel's method of calculating | ||||
* this field. | * this field. | ||||
*/ | */ | ||||
Show All 25 Lines | #define pmap_resident_count(pm) ((pm)->pm_stats.resident_count) | ||||
if (proc.p_comm[0] != 0) | if (proc.p_comm[0] != 0) | ||||
strlcpy(kp->ki_comm, proc.p_comm, MAXCOMLEN); | strlcpy(kp->ki_comm, proc.p_comm, MAXCOMLEN); | ||||
(void)kvm_read(kd, (u_long)proc.p_sysent, (char *)&sysent, | (void)kvm_read(kd, (u_long)proc.p_sysent, (char *)&sysent, | ||||
sizeof(sysent)); | sizeof(sysent)); | ||||
(void)kvm_read(kd, (u_long)sysent.sv_name, (char *)&svname, | (void)kvm_read(kd, (u_long)sysent.sv_name, (char *)&svname, | ||||
sizeof(svname)); | sizeof(svname)); | ||||
if (svname[0] != 0) | if (svname[0] != 0) | ||||
strlcpy(kp->ki_emul, svname, KI_EMULNAMELEN); | strlcpy(kp->ki_emul, svname, KI_EMULNAMELEN); | ||||
kp->ki_runtime = cputick2usec(proc.p_rux.rux_runtime); | |||||
kp->ki_pid = proc.p_pid; | |||||
kp->ki_xstat = KW_EXITCODE(proc.p_xexit, proc.p_xsig); | |||||
kp->ki_acflag = proc.p_acflag; | |||||
kp->ki_lock = proc.p_lock; | |||||
kp->ki_tdev_freebsd11 = kp->ki_tdev; /* truncate */ | |||||
/* Per-thread items; iterate as appropriate. */ | |||||
td = TAILQ_FIRST(&proc.p_threads); | |||||
for (first_thread = true; cnt < maxcnt && td != NULL && | |||||
(first_thread || (what & KERN_PROC_INC_THREAD)); | |||||
first_thread = false) { | |||||
if (proc.p_state != PRS_ZOMBIE) { | |||||
if (KREAD(kd, (u_long)td, &mtd)) { | |||||
_kvm_err(kd, kd->program, | |||||
"can't read thread at %p", td); | |||||
return (-1); | |||||
} | |||||
if (what & KERN_PROC_INC_THREAD) | |||||
td = TAILQ_NEXT(&mtd, td_plist); | |||||
} else | |||||
td = NULL; | |||||
if ((proc.p_state != PRS_ZOMBIE) && mtd.td_wmesg) | |||||
(void)kvm_read(kd, (u_long)mtd.td_wmesg, | |||||
kp->ki_wmesg, WMESGLEN); | |||||
else | |||||
memset(kp->ki_wmesg, 0, WMESGLEN); | |||||
if (proc.p_pgrp == NULL) { | |||||
kp->ki_kiflag = 0; | |||||
} else { | |||||
kp->ki_kiflag = sess.s_ttyvp ? KI_CTTY : 0; | |||||
if (sess.s_leader == p) | |||||
kp->ki_kiflag |= KI_SLEADER; | |||||
} | |||||
if ((proc.p_state != PRS_ZOMBIE) && | if ((proc.p_state != PRS_ZOMBIE) && | ||||
(mtd.td_blocked != 0)) { | (mtd.td_blocked != 0)) { | ||||
kp->ki_kiflag |= KI_LOCKBLOCK; | kp->ki_kiflag |= KI_LOCKBLOCK; | ||||
if (mtd.td_lockname) | if (mtd.td_lockname) | ||||
(void)kvm_read(kd, | (void)kvm_read(kd, | ||||
(u_long)mtd.td_lockname, | (u_long)mtd.td_lockname, | ||||
kp->ki_lockname, LOCKNAMELEN); | kp->ki_lockname, LOCKNAMELEN); | ||||
else | |||||
memset(kp->ki_lockname, 0, | |||||
LOCKNAMELEN); | |||||
kp->ki_lockname[LOCKNAMELEN] = 0; | kp->ki_lockname[LOCKNAMELEN] = 0; | ||||
} | } else | ||||
kp->ki_runtime = cputick2usec(proc.p_rux.rux_runtime); | kp->ki_kiflag &= ~KI_LOCKBLOCK; | ||||
kp->ki_pid = proc.p_pid; | |||||
kp->ki_siglist = proc.p_siglist; | kp->ki_siglist = proc.p_siglist; | ||||
if (proc.p_state != PRS_ZOMBIE) { | |||||
SIGSETOR(kp->ki_siglist, mtd.td_siglist); | SIGSETOR(kp->ki_siglist, mtd.td_siglist); | ||||
kp->ki_sigmask = mtd.td_sigmask; | kp->ki_sigmask = mtd.td_sigmask; | ||||
kp->ki_xstat = KW_EXITCODE(proc.p_xexit, proc.p_xsig); | |||||
kp->ki_acflag = proc.p_acflag; | |||||
kp->ki_lock = proc.p_lock; | |||||
if (proc.p_state != PRS_ZOMBIE) { | |||||
kp->ki_swtime = (ticks - proc.p_swtick) / hz; | kp->ki_swtime = (ticks - proc.p_swtick) / hz; | ||||
kp->ki_flag = proc.p_flag; | kp->ki_flag = proc.p_flag; | ||||
kp->ki_sflag = 0; | kp->ki_sflag = 0; | ||||
kp->ki_nice = proc.p_nice; | kp->ki_nice = proc.p_nice; | ||||
kp->ki_traceflag = proc.p_traceflag; | kp->ki_traceflag = proc.p_traceflag; | ||||
if (proc.p_state == PRS_NORMAL) { | if (proc.p_state == PRS_NORMAL) { | ||||
if (TD_ON_RUNQ(&mtd) || | if (TD_ON_RUNQ(&mtd) || | ||||
TD_CAN_RUN(&mtd) || | TD_CAN_RUN(&mtd) || | ||||
TD_IS_RUNNING(&mtd)) { | TD_IS_RUNNING(&mtd)) { | ||||
kp->ki_stat = SRUN; | kp->ki_stat = SRUN; | ||||
} else if (mtd.td_state == | } else if (mtd.td_state == | ||||
TDS_INHIBITED) { | TDS_INHIBITED) { | ||||
if (P_SHOULDSTOP(&proc)) { | if (P_SHOULDSTOP(&proc)) { | ||||
kp->ki_stat = SSTOP; | kp->ki_stat = SSTOP; | ||||
} else if ( | } else if ( | ||||
TD_IS_SLEEPING(&mtd)) { | TD_IS_SLEEPING(&mtd)) { | ||||
kp->ki_stat = SSLEEP; | kp->ki_stat = SSLEEP; | ||||
} else if (TD_ON_LOCK(&mtd)) { | } else if (TD_ON_LOCK(&mtd)) { | ||||
kp->ki_stat = SLOCK; | kp->ki_stat = SLOCK; | ||||
} else { | } else { | ||||
kp->ki_stat = SWAIT; | kp->ki_stat = SWAIT; | ||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
kp->ki_stat = SIDL; | kp->ki_stat = SIDL; | ||||
} | } | ||||
/* Stuff from the thread */ | /* Stuff from the thread */ | ||||
kp->ki_pri.pri_level = mtd.td_priority; | kp->ki_pri.pri_level = mtd.td_priority; | ||||
kp->ki_pri.pri_native = mtd.td_base_pri; | kp->ki_pri.pri_native = mtd.td_base_pri; | ||||
kp->ki_lastcpu = mtd.td_lastcpu; | kp->ki_lastcpu = mtd.td_lastcpu; | ||||
kp->ki_wchan = mtd.td_wchan; | kp->ki_wchan = mtd.td_wchan; | ||||
kp->ki_oncpu = mtd.td_oncpu; | kp->ki_oncpu = mtd.td_oncpu; | ||||
if (mtd.td_name[0] != '\0') | if (mtd.td_name[0] != '\0') | ||||
strlcpy(kp->ki_tdname, mtd.td_name, sizeof(kp->ki_tdname)); | strlcpy(kp->ki_tdname, mtd.td_name, | ||||
sizeof(kp->ki_tdname)); | |||||
else | |||||
memset(kp->ki_tdname, 0, | |||||
sizeof(kp->ki_tdname)); | |||||
kp->ki_pctcpu = 0; | kp->ki_pctcpu = 0; | ||||
kp->ki_rqindex = 0; | kp->ki_rqindex = 0; | ||||
/* | /* | ||||
* Note: legacy fields; wraps at NO_CPU_OLD or the | * Note: legacy fields; wraps at NO_CPU_OLD | ||||
* old max CPU value as appropriate | * or the old max CPU value as appropriate | ||||
*/ | */ | ||||
if (mtd.td_lastcpu == NOCPU) | if (mtd.td_lastcpu == NOCPU) | ||||
kp->ki_lastcpu_old = NOCPU_OLD; | kp->ki_lastcpu_old = NOCPU_OLD; | ||||
else if (mtd.td_lastcpu > MAXCPU_OLD) | else if (mtd.td_lastcpu > MAXCPU_OLD) | ||||
kp->ki_lastcpu_old = MAXCPU_OLD; | kp->ki_lastcpu_old = MAXCPU_OLD; | ||||
else | else | ||||
kp->ki_lastcpu_old = mtd.td_lastcpu; | kp->ki_lastcpu_old = mtd.td_lastcpu; | ||||
if (mtd.td_oncpu == NOCPU) | if (mtd.td_oncpu == NOCPU) | ||||
kp->ki_oncpu_old = NOCPU_OLD; | kp->ki_oncpu_old = NOCPU_OLD; | ||||
else if (mtd.td_oncpu > MAXCPU_OLD) | else if (mtd.td_oncpu > MAXCPU_OLD) | ||||
kp->ki_oncpu_old = MAXCPU_OLD; | kp->ki_oncpu_old = MAXCPU_OLD; | ||||
else | else | ||||
kp->ki_oncpu_old = mtd.td_oncpu; | kp->ki_oncpu_old = mtd.td_oncpu; | ||||
kp->ki_tid = mtd.td_tid; | |||||
} else { | } else { | ||||
memset(&kp->ki_sigmask, 0, | |||||
sizeof(kp->ki_sigmask)); | |||||
kp->ki_stat = SZOMB; | kp->ki_stat = SZOMB; | ||||
kp->ki_tid = 0; | |||||
} | } | ||||
kp->ki_tdev_freebsd11 = kp->ki_tdev; /* truncate */ | |||||
bcopy(&kinfo_proc, bp, sizeof(kinfo_proc)); | bcopy(&kinfo_proc, bp, sizeof(kinfo_proc)); | ||||
++bp; | ++bp; | ||||
++cnt; | ++cnt; | ||||
} | } | ||||
} | |||||
return (cnt); | return (cnt); | ||||
} | } | ||||
/* | /* | ||||
* Build proc info array by reading in proc list from a crash dump. | * Build proc info array by reading in proc list from a crash dump. | ||||
* Return number of procs read. maxcnt is the max we will read. | * Return number of procs read. maxcnt is the max we will read. | ||||
*/ | */ | ||||
static int | static int | ||||
kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc, | kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc, | ||||
u_long a_zombproc, int maxcnt) | u_long a_zombproc, int maxcnt) | ||||
{ | { | ||||
struct kinfo_proc *bp = kd->procbase; | struct kinfo_proc *bp = kd->procbase; | ||||
int acnt, zcnt; | int acnt, zcnt = 0; | ||||
struct proc *p; | struct proc *p; | ||||
if (KREAD(kd, a_allproc, &p)) { | if (KREAD(kd, a_allproc, &p)) { | ||||
_kvm_err(kd, kd->program, "cannot read allproc"); | _kvm_err(kd, kd->program, "cannot read allproc"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt); | acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt); | ||||
if (acnt < 0) | if (acnt < 0) | ||||
return (acnt); | return (acnt); | ||||
if (a_zombproc != 0) { | |||||
if (KREAD(kd, a_zombproc, &p)) { | if (KREAD(kd, a_zombproc, &p)) { | ||||
_kvm_err(kd, kd->program, "cannot read zombproc"); | _kvm_err(kd, kd->program, "cannot read zombproc"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt); | zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt); | ||||
if (zcnt < 0) | if (zcnt < 0) | ||||
zcnt = 0; | zcnt = 0; | ||||
} | |||||
return (acnt + zcnt); | return (acnt + zcnt); | ||||
} | } | ||||
struct kinfo_proc * | struct kinfo_proc * | ||||
kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) | kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt) | ||||
{ | { | ||||
int mib[4], st, nprocs; | int mib[4], st, nprocs; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | if (size > 0 && | ||||
"kinfo_proc size mismatch (expected %zu, got %d)", | "kinfo_proc size mismatch (expected %zu, got %d)", | ||||
sizeof(struct kinfo_proc), | sizeof(struct kinfo_proc), | ||||
kd->procbase->ki_structsize); | kd->procbase->ki_structsize); | ||||
return (0); | return (0); | ||||
} | } | ||||
liveout: | liveout: | ||||
nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize; | nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize; | ||||
} else { | } else { | ||||
struct nlist nl[7], *p; | struct nlist nl[6], *p; | ||||
struct nlist nlz[2]; | |||||
nl[0].n_name = "_nprocs"; | nl[0].n_name = "_nprocs"; | ||||
nl[1].n_name = "_allproc"; | nl[1].n_name = "_allproc"; | ||||
nl[2].n_name = "_zombproc"; | nl[2].n_name = "_ticks"; | ||||
nl[3].n_name = "_ticks"; | nl[3].n_name = "_hz"; | ||||
nl[4].n_name = "_hz"; | nl[4].n_name = "_cpu_tick_frequency"; | ||||
nl[5].n_name = "_cpu_tick_frequency"; | nl[5].n_name = 0; | ||||
nl[6].n_name = 0; | |||||
nlz[0].n_name = "_zombproc"; | |||||
nlz[1].n_name = 0; | |||||
if (!kd->arch->ka_native(kd)) { | if (!kd->arch->ka_native(kd)) { | ||||
_kvm_err(kd, kd->program, | _kvm_err(kd, kd->program, | ||||
"cannot read procs from non-native core"); | "cannot read procs from non-native core"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (kvm_nlist(kd, nl) != 0) { | if (kvm_nlist(kd, nl) != 0) { | ||||
for (p = nl; p->n_type != 0; ++p) | for (p = nl; p->n_type != 0; ++p) | ||||
; | ; | ||||
_kvm_err(kd, kd->program, | _kvm_err(kd, kd->program, | ||||
"%s: no such symbol", p->n_name); | "%s: no such symbol", p->n_name); | ||||
return (0); | return (0); | ||||
} | } | ||||
(void) kvm_nlist(kd, nlz); /* attempt to get zombproc */ | |||||
if (KREAD(kd, nl[0].n_value, &nprocs)) { | if (KREAD(kd, nl[0].n_value, &nprocs)) { | ||||
_kvm_err(kd, kd->program, "can't read nprocs"); | _kvm_err(kd, kd->program, "can't read nprocs"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (KREAD(kd, nl[3].n_value, &ticks)) { | /* | ||||
* If returning all threads, we don't know how many that | |||||
* might be. Presume that there are, on average, no more | |||||
* than 10 threads per process. | |||||
*/ | |||||
if (op == KERN_PROC_ALL || (op & KERN_PROC_INC_THREAD)) | |||||
nprocs *= 10; /* XXX */ | |||||
if (KREAD(kd, nl[2].n_value, &ticks)) { | |||||
_kvm_err(kd, kd->program, "can't read ticks"); | _kvm_err(kd, kd->program, "can't read ticks"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (KREAD(kd, nl[4].n_value, &hz)) { | if (KREAD(kd, nl[3].n_value, &hz)) { | ||||
_kvm_err(kd, kd->program, "can't read hz"); | _kvm_err(kd, kd->program, "can't read hz"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (KREAD(kd, nl[5].n_value, &cpu_tick_frequency)) { | if (KREAD(kd, nl[4].n_value, &cpu_tick_frequency)) { | ||||
_kvm_err(kd, kd->program, | _kvm_err(kd, kd->program, | ||||
"can't read cpu_tick_frequency"); | "can't read cpu_tick_frequency"); | ||||
return (0); | return (0); | ||||
} | } | ||||
size = nprocs * sizeof(struct kinfo_proc); | size = nprocs * sizeof(struct kinfo_proc); | ||||
kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); | kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); | ||||
if (kd->procbase == NULL) | if (kd->procbase == NULL) | ||||
return (0); | return (0); | ||||
nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, | nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, | ||||
nl[2].n_value, nprocs); | nlz[0].n_value, nprocs); | ||||
if (nprocs <= 0) { | if (nprocs <= 0) { | ||||
_kvm_freeprocs(kd); | _kvm_freeprocs(kd); | ||||
nprocs = 0; | nprocs = 0; | ||||
} | } | ||||
#ifdef notdef | #ifdef notdef | ||||
else { | else { | ||||
size = nprocs * sizeof(struct kinfo_proc); | size = nprocs * sizeof(struct kinfo_proc); | ||||
kd->procbase = realloc(kd->procbase, size); | kd->procbase = realloc(kd->procbase, size); | ||||
▲ Show 20 Lines • Show All 117 Lines • Show Last 20 Lines |