⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kvm_proc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * 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 + -