📄 kvm_proc.c
字号:
* 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; st = sysctl(mib, 4, NULL, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); if (kd->procbase == 0) return (0); st = sysctl(mib, 4, kd->procbase, &size, NULL, 0); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } if (size % sizeof(struct kinfo_proc) != 0) { _kvm_err(kd, kd->program, "proc size mismatch (%d total, %d chunks)", size, sizeof(struct kinfo_proc)); return (0); } nprocs = size / sizeof(struct kinfo_proc); } else { struct nlist nl[4], *p; nl[0].n_name = "_nprocs"; nl[1].n_name = "_allproc"; nl[2].n_name = "_zombproc"; nl[3].n_name = 0; if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) ; _kvm_err(kd, kd->program, "%s: no such symbol", p->n_name); return (0); } if (KREAD(kd, nl[0].n_value, &nprocs)) { _kvm_err(kd, kd->program, "can't read nprocs"); return (0); } size = nprocs * sizeof(struct kinfo_proc); kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); if (kd->procbase == 0) return (0); nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, nl[2].n_value, nprocs);#ifdef notdef size = nprocs * sizeof(struct kinfo_proc); (void)realloc(kd->procbase, size);#endif } *cnt = nprocs; return (kd->procbase);}void_kvm_freeprocs(kd) kvm_t *kd;{ if (kd->procbase) { free(kd->procbase); kd->procbase = 0; }}void *_kvm_realloc(kd, p, n) kvm_t *kd; void *p; size_t n;{ void *np = (void *)realloc(p, n); if (np == 0) _kvm_err(kd, kd->program, "out of memory"); return (np);}#ifndef MAX#define MAX(a, b) ((a) > (b) ? (a) : (b))#endif/* * Read in an argument vector from the user address space of process p. * addr if the user-space base address of narg null-terminated contiguous * strings. This is used to read in both the command arguments and * environment strings. Read at most maxcnt characters of strings. */static char **kvm_argv(kd, p, addr, narg, maxcnt) kvm_t *kd; struct proc *p; register u_long addr; register int narg; register int maxcnt;{ register char *cp; register int len, cc; register char **argv; /* * Check that there aren't an unreasonable number of agruments, * and that the address is in user space. */ if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS) return (0); if (kd->argv == 0) { /* * Try to avoid reallocs. */ kd->argc = MAX(narg + 1, 32); kd->argv = (char **)_kvm_malloc(kd, kd->argc * sizeof(*kd->argv)); if (kd->argv == 0) return (0); } else if (narg + 1 > kd->argc) { kd->argc = MAX(2 * kd->argc, narg + 1); kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * sizeof(*kd->argv)); if (kd->argv == 0) return (0); } if (kd->argspc == 0) { kd->argspc = (char *)_kvm_malloc(kd, NBPG); if (kd->argspc == 0) return (0); kd->arglen = NBPG; } cp = kd->argspc; argv = kd->argv; *argv = cp; len = 0; /* * Loop over pages, filling in the argument vector. */ while (addr < VM_MAXUSER_ADDRESS) { cc = NBPG - (addr & PGOFSET); if (maxcnt > 0 && cc > maxcnt - len) cc = maxcnt - len;; if (len + cc > kd->arglen) { register int off; register char **pp; register char *op = kd->argspc; kd->arglen *= 2; kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, kd->arglen); if (kd->argspc == 0) return (0); cp = &kd->argspc[len]; /* * Adjust argv pointers in case realloc moved * the string space. */ off = kd->argspc - op; for (pp = kd->argv; pp < argv; ++pp) *pp += off; } if (kvm_uread(kd, p, addr, cp, cc) != cc) /* XXX */ return (0); len += cc; addr += cc; if (maxcnt == 0 && len > 16 * NBPG) /* sanity */ return (0); while (--cc >= 0) { if (*cp++ == 0) { if (--narg <= 0) { *++argv = 0; return (kd->argv); } else *++argv = cp; } } if (maxcnt > 0 && len >= maxcnt) { /* * We're stopping prematurely. Terminate the * argv and current string. */ *++argv = 0; *cp = 0; return (kd->argv); } }}static voidps_str_a(p, addr, n) struct ps_strings *p; u_long *addr; int *n;{ *addr = (u_long)p->ps_argvstr; *n = p->ps_nargvstr;}static voidps_str_e(p, addr, n) struct ps_strings *p; u_long *addr; int *n;{ *addr = (u_long)p->ps_envstr; *n = p->ps_nenvstr;}/* * Determine if the proc indicated by p is still active. * This test is not 100% foolproof in theory, but chances of * being wrong are very low. */static intproc_verify(kd, kernp, p) kvm_t *kd; u_long kernp; const struct proc *p;{ struct proc kernproc; /* * Just read in the whole proc. It's not that big relative * to the cost of the read system call. */ if (kvm_read(kd, kernp, (char *)&kernproc, sizeof(kernproc)) != sizeof(kernproc)) return (0); return (p->p_pid == kernproc.p_pid && (kernproc.p_stat != SZOMB || p->p_stat == SZOMB));}static char **kvm_doargv(kd, kp, nchr, info) kvm_t *kd; const struct kinfo_proc *kp; int nchr; int (*info)(struct ps_strings*, u_long *, int *);{ register const struct proc *p = &kp->kp_proc; register char **ap; u_long addr; int cnt; struct ps_strings arginfo; /* * Pointers are stored at the top of the user stack. */ if (p->p_stat == SZOMB || kvm_uread(kd, p, USRSTACK - sizeof(arginfo), (char *)&arginfo, sizeof(arginfo)) != sizeof(arginfo)) return (0); (*info)(&arginfo, &addr, &cnt); ap = kvm_argv(kd, p, addr, cnt, nchr); /* * For live kernels, make sure this process didn't go away. */ if (ap != 0 && ISALIVE(kd) && !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p)) ap = 0; return (ap);}/* * Get the command args. This code is now machine independent. */char **kvm_getargv(kd, kp, nchr) kvm_t *kd; const struct kinfo_proc *kp; int nchr;{ return (kvm_doargv(kd, kp, nchr, ps_str_a));}char **kvm_getenvv(kd, kp, nchr) kvm_t *kd; const struct kinfo_proc *kp; int nchr;{ return (kvm_doargv(kd, kp, nchr, ps_str_e));}/* * Read from user space. The user context is given by p. */ssize_tkvm_uread(kd, p, uva, buf, len) kvm_t *kd; register struct proc *p; register u_long uva; register char *buf; register size_t len;{ register char *cp; cp = buf; while (len > 0) { u_long pa; register int cc; cc = _kvm_uvatop(kd, p, uva, &pa); if (cc > 0) { if (cc > len) cc = len; errno = 0; if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) { _kvm_err(kd, 0, "invalid address (%x)", uva); break; } cc = read(kd->pmfd, cp, cc); if (cc < 0) { _kvm_syserr(kd, 0, _PATH_MEM); break; } else if (cc < len) { _kvm_err(kd, kd->program, "short read"); break; } } else if (ISALIVE(kd)) { /* try swap */ register char *dp; int cnt; dp = kvm_readswap(kd, p, uva, &cnt); if (dp == 0) { _kvm_err(kd, 0, "invalid address (%x)", uva); return (0); } cc = MIN(cnt, len); bcopy(dp, cp, cc); } else break; cp += cc; uva += cc; len -= cc; } return (ssize_t)(cp - buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -