kvm_proc.c revision 72377
1/*-
2 * Copyright (c) 1989, 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software developed by the Computer Systems
6 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
7 * BG 91-66 and contributed to Berkeley.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by the University of
20 *	California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD: head/lib/libkvm/kvm_proc.c 72377 2001-02-12 00:21:38Z jake $
38 */
39
40#if defined(LIBC_SCCS) && !defined(lint)
41static char sccsid[] = "@(#)kvm_proc.c	8.3 (Berkeley) 9/23/93";
42#endif /* LIBC_SCCS and not lint */
43
44/*
45 * Proc traversal interface for kvm.  ps and w are (probably) the exclusive
46 * users of this code, so we've factored it out into a separate module.
47 * Thus, we keep this grunge out of the other kvm applications (i.e.,
48 * most other applications are interested only in open/close/read/nlist).
49 */
50
51#include <sys/param.h>
52#include <sys/user.h>
53#include <sys/proc.h>
54#include <sys/exec.h>
55#include <sys/stat.h>
56#include <sys/ioctl.h>
57#include <sys/tty.h>
58#include <sys/file.h>
59#include <stdio.h>
60#include <stdlib.h>
61#include <unistd.h>
62#include <nlist.h>
63#include <kvm.h>
64
65#include <vm/vm.h>
66#include <vm/vm_param.h>
67#include <vm/swap_pager.h>
68
69#include <sys/sysctl.h>
70
71#include <limits.h>
72#include <memory.h>
73#include <paths.h>
74
75#include "kvm_private.h"
76
77#if used
78static char *
79kvm_readswap(kd, p, va, cnt)
80	kvm_t *kd;
81	const struct proc *p;
82	u_long va;
83	u_long *cnt;
84{
85#ifdef __FreeBSD__
86	/* XXX Stubbed out, our vm system is differnet */
87	_kvm_err(kd, kd->program, "kvm_readswap not implemented");
88	return(0);
89#endif	/* __FreeBSD__ */
90}
91#endif
92
93#define KREAD(kd, addr, obj) \
94	(kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
95
96/*
97 * Read proc's from memory file into buffer bp, which has space to hold
98 * at most maxcnt procs.
99 */
100static int
101kvm_proclist(kd, what, arg, p, bp, maxcnt)
102	kvm_t *kd;
103	int what, arg;
104	struct proc *p;
105	struct kinfo_proc *bp;
106	int maxcnt;
107{
108	register int cnt = 0;
109	struct kinfo_proc kinfo_proc, *kp;
110	struct pgrp pgrp;
111	struct session sess;
112	struct tty tty;
113	struct vmspace vmspace;
114	struct procsig procsig;
115	struct pcred pcred;
116	struct pstats pstats;
117	struct ucred ucred;
118	struct proc proc;
119	struct proc pproc;
120
121	kp = &kinfo_proc;
122	kp->ki_structsize = sizeof(kinfo_proc);
123	for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) {
124		if (KREAD(kd, (u_long)p, &proc)) {
125			_kvm_err(kd, kd->program, "can't read proc at %x", p);
126			return (-1);
127		}
128		if (KREAD(kd, (u_long)proc.p_cred, &pcred) == 0) {
129			kp->ki_ruid = pcred.p_ruid;
130			kp->ki_svuid = pcred.p_svuid;
131			kp->ki_rgid = pcred.p_rgid;
132			kp->ki_svgid = pcred.p_svgid;
133			(void)(KREAD(kd, (u_long)pcred.pc_ucred, &ucred));
134			kp->ki_ngroups = ucred.cr_ngroups;
135			bcopy(ucred.cr_groups, kp->ki_groups,
136			    NGROUPS * sizeof(gid_t));
137			kp->ki_uid = ucred.cr_uid;
138		}
139
140		switch(what) {
141
142		case KERN_PROC_PID:
143			if (proc.p_pid != (pid_t)arg)
144				continue;
145			break;
146
147		case KERN_PROC_UID:
148			if (kp->ki_uid != (uid_t)arg)
149				continue;
150			break;
151
152		case KERN_PROC_RUID:
153			if (kp->ki_ruid != (uid_t)arg)
154				continue;
155			break;
156		}
157		/*
158		 * We're going to add another proc to the set.  If this
159		 * will overflow the buffer, assume the reason is because
160		 * nprocs (or the proc list) is corrupt and declare an error.
161		 */
162		if (cnt >= maxcnt) {
163			_kvm_err(kd, kd->program, "nprocs corrupt");
164			return (-1);
165		}
166		/*
167		 * gather kinfo_proc
168		 */
169		kp->ki_paddr = p;
170		kp->ki_addr = proc.p_addr;
171		kp->ki_args = proc.p_args;
172		kp->ki_tracep = proc.p_tracep;
173		kp->ki_textvp = proc.p_textvp;
174		kp->ki_fd = proc.p_fd;
175		kp->ki_vmspace = proc.p_vmspace;
176		if (proc.p_procsig != NULL) {
177			if (KREAD(kd, (u_long)proc.p_procsig, &procsig)) {
178				_kvm_err(kd, kd->program,
179				    "can't read procsig at %x", proc.p_procsig);
180				return (-1);
181			}
182			kp->ki_sigignore = procsig.ps_sigignore;
183			kp->ki_sigcatch = procsig.ps_sigcatch;
184		}
185		if ((proc.p_sflag & PS_INMEM) && proc.p_stats != NULL) {
186			if (KREAD(kd, (u_long)proc.p_stats, &pstats)) {
187				_kvm_err(kd, kd->program,
188				    "can't read stats at %x", proc.p_stats);
189				return (-1);
190			}
191			kp->ki_start = pstats.p_start;
192			kp->ki_rusage = pstats.p_ru;
193			kp->ki_childtime.tv_sec = pstats.p_cru.ru_utime.tv_sec +
194			    pstats.p_cru.ru_stime.tv_sec;
195			kp->ki_childtime.tv_usec =
196			    pstats.p_cru.ru_utime.tv_usec +
197			    pstats.p_cru.ru_stime.tv_usec;
198		}
199		if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
200			_kvm_err(kd, kd->program, "can't read pgrp at %x",
201				 proc.p_pgrp);
202			return (-1);
203		}
204		if (proc.p_oppid)
205			kp->ki_ppid = proc.p_oppid;
206		else if (proc.p_pptr) {
207			if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
208				_kvm_err(kd, kd->program,
209				    "can't read pproc at %x", proc.p_pptr);
210				return (-1);
211			}
212			kp->ki_ppid = pproc.p_pid;
213		} else
214			kp->ki_ppid = 0;
215		kp->ki_pgid = pgrp.pg_id;
216		kp->ki_jobc = pgrp.pg_jobc;
217		if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
218			_kvm_err(kd, kd->program, "can't read session at %x",
219				pgrp.pg_session);
220			return (-1);
221		}
222		kp->ki_sid = sess.s_sid;
223		(void)memcpy(kp->ki_login, sess.s_login,
224						sizeof(kp->ki_login));
225		kp->ki_kiflag = sess.s_ttyvp ? KI_CTTY : 0;
226		if (sess.s_leader == p)
227			kp->ki_kiflag |= KI_SLEADER;
228		if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
229			if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
230				_kvm_err(kd, kd->program,
231					 "can't read tty at %x", sess.s_ttyp);
232				return (-1);
233			}
234			kp->ki_tdev = tty.t_dev;
235			if (tty.t_pgrp != NULL) {
236				if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
237					_kvm_err(kd, kd->program,
238						 "can't read tpgrp at &x",
239						tty.t_pgrp);
240					return (-1);
241				}
242				kp->ki_tpgid = pgrp.pg_id;
243			} else
244				kp->ki_tpgid = -1;
245			if (tty.t_session != NULL) {
246				if (KREAD(kd, (u_long)tty.t_session, &sess)) {
247					_kvm_err(kd, kd->program,
248					    "can't read session at %x",
249					    tty.t_session);
250					return (-1);
251				}
252				kp->ki_tsid = sess.s_sid;
253			}
254		} else
255			kp->ki_tdev = NODEV;
256		if (proc.p_wmesg)
257			(void)kvm_read(kd, (u_long)proc.p_wmesg,
258			    kp->ki_wmesg, WMESGLEN);
259
260#ifdef sparc
261		(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_rssize,
262		    (char *)&kp->ki_rssize,
263		    sizeof(kp->ki_rssize));
264		(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_tsize,
265		    (char *)&kp->ki_tsize,
266		    3 * sizeof(kp->ki_rssize));	/* XXX */
267#else
268		(void)kvm_read(kd, (u_long)proc.p_vmspace,
269		    (char *)&vmspace, sizeof(vmspace));
270		kp->ki_size = vmspace.vm_map.size;
271		kp->ki_rssize = vmspace.vm_swrss; /* XXX */
272		kp->ki_swrss = vmspace.vm_swrss;
273		kp->ki_tsize = vmspace.vm_tsize;
274		kp->ki_dsize = vmspace.vm_dsize;
275		kp->ki_ssize = vmspace.vm_ssize;
276#endif
277
278		switch (what) {
279
280		case KERN_PROC_PGRP:
281			if (kp->ki_pgid != (pid_t)arg)
282				continue;
283			break;
284
285		case KERN_PROC_TTY:
286			if ((proc.p_flag & P_CONTROLT) == 0 ||
287			     kp->ki_tdev != (dev_t)arg)
288				continue;
289			break;
290		}
291		if (proc.p_comm[0] != 0) {
292			strncpy(kp->ki_comm, proc.p_comm, MAXCOMLEN);
293			kp->ki_comm[MAXCOMLEN] = 0;
294		}
295		if (proc.p_blocked != 0) {
296			kp->ki_kiflag |= KI_MTXBLOCK;
297			if (proc.p_mtxname)
298				(void)kvm_read(kd, (u_long)proc.p_mtxname,
299				    kp->ki_mtxname, MTXNAMELEN);
300			kp->ki_mtxname[MTXNAMELEN] = 0;
301		}
302		kp->ki_runtime = proc.p_runtime;
303		kp->ki_pid = proc.p_pid;
304		kp->ki_siglist = proc.p_siglist;
305		kp->ki_sigmask = proc.p_sigmask;
306		kp->ki_xstat = proc.p_xstat;
307		kp->ki_acflag = proc.p_acflag;
308		kp->ki_pctcpu = proc.p_pctcpu;
309		kp->ki_estcpu = proc.p_estcpu;
310		kp->ki_slptime = proc.p_slptime;
311		kp->ki_swtime = proc.p_swtime;
312		kp->ki_flag = proc.p_flag;
313		kp->ki_sflag = proc.p_sflag;
314		kp->ki_wchan = proc.p_wchan;
315		kp->ki_traceflag = proc.p_traceflag;
316		kp->ki_stat = proc.p_stat;
317		kp->ki_pri = proc.p_pri;
318		kp->ki_nice = proc.p_nice;
319		kp->ki_lock = proc.p_lock;
320		kp->ki_rqindex = proc.p_rqindex;
321		kp->ki_oncpu = proc.p_oncpu;
322		kp->ki_lastcpu = proc.p_lastcpu;
323		bcopy(&kinfo_proc, bp, sizeof(kinfo_proc));
324		++bp;
325		++cnt;
326	}
327	return (cnt);
328}
329
330/*
331 * Build proc info array by reading in proc list from a crash dump.
332 * Return number of procs read.  maxcnt is the max we will read.
333 */
334static int
335kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt)
336	kvm_t *kd;
337	int what, arg;
338	u_long a_allproc;
339	u_long a_zombproc;
340	int maxcnt;
341{
342	register struct kinfo_proc *bp = kd->procbase;
343	register int acnt, zcnt;
344	struct proc *p;
345
346	if (KREAD(kd, a_allproc, &p)) {
347		_kvm_err(kd, kd->program, "cannot read allproc");
348		return (-1);
349	}
350	acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
351	if (acnt < 0)
352		return (acnt);
353
354	if (KREAD(kd, a_zombproc, &p)) {
355		_kvm_err(kd, kd->program, "cannot read zombproc");
356		return (-1);
357	}
358	zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
359	if (zcnt < 0)
360		zcnt = 0;
361
362	return (acnt + zcnt);
363}
364
365struct kinfo_proc *
366kvm_getprocs(kd, op, arg, cnt)
367	kvm_t *kd;
368	int op, arg;
369	int *cnt;
370{
371	int mib[4], st, nprocs;
372	size_t size;
373
374	if (kd->procbase != 0) {
375		free((void *)kd->procbase);
376		/*
377		 * Clear this pointer in case this call fails.  Otherwise,
378		 * kvm_close() will free it again.
379		 */
380		kd->procbase = 0;
381	}
382	if (ISALIVE(kd)) {
383		size = 0;
384		mib[0] = CTL_KERN;
385		mib[1] = KERN_PROC;
386		mib[2] = op;
387		mib[3] = arg;
388		st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, NULL, &size, NULL, 0);
389		if (st == -1) {
390			_kvm_syserr(kd, kd->program, "kvm_getprocs");
391			return (0);
392		}
393		do {
394			size += size / 10;
395			kd->procbase = (struct kinfo_proc *)
396			    _kvm_realloc(kd, kd->procbase, size);
397			if (kd->procbase == 0)
398				return (0);
399			st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4,
400			    kd->procbase, &size, NULL, 0);
401		} while (st == -1 && errno == ENOMEM);
402		if (st == -1) {
403			_kvm_syserr(kd, kd->program, "kvm_getprocs");
404			return (0);
405		}
406		if (kd->procbase->ki_structsize != sizeof(struct kinfo_proc)) {
407			_kvm_err(kd, kd->program,
408			    "kinfo_proc size mismatch (expected %d, got %d)",
409			    sizeof(struct kinfo_proc),
410			    kd->procbase->ki_structsize);
411			return (0);
412		}
413		nprocs = size / kd->procbase->ki_structsize;
414	} else {
415		struct nlist nl[4], *p;
416
417		nl[0].n_name = "_nprocs";
418		nl[1].n_name = "_allproc";
419		nl[2].n_name = "_zombproc";
420		nl[3].n_name = 0;
421
422		if (kvm_nlist(kd, nl) != 0) {
423			for (p = nl; p->n_type != 0; ++p)
424				;
425			_kvm_err(kd, kd->program,
426				 "%s: no such symbol", p->n_name);
427			return (0);
428		}
429		if (KREAD(kd, nl[0].n_value, &nprocs)) {
430			_kvm_err(kd, kd->program, "can't read nprocs");
431			return (0);
432		}
433		size = nprocs * sizeof(struct kinfo_proc);
434		kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
435		if (kd->procbase == 0)
436			return (0);
437
438		nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
439				      nl[2].n_value, nprocs);
440#ifdef notdef
441		size = nprocs * sizeof(struct kinfo_proc);
442		(void)realloc(kd->procbase, size);
443#endif
444	}
445	*cnt = nprocs;
446	return (kd->procbase);
447}
448
449void
450_kvm_freeprocs(kd)
451	kvm_t *kd;
452{
453	if (kd->procbase) {
454		free(kd->procbase);
455		kd->procbase = 0;
456	}
457}
458
459void *
460_kvm_realloc(kd, p, n)
461	kvm_t *kd;
462	void *p;
463	size_t n;
464{
465	void *np = (void *)realloc(p, n);
466
467	if (np == 0) {
468		free(p);
469		_kvm_err(kd, kd->program, "out of memory");
470	}
471	return (np);
472}
473
474#ifndef MAX
475#define MAX(a, b) ((a) > (b) ? (a) : (b))
476#endif
477
478/*
479 * Read in an argument vector from the user address space of process kp.
480 * addr if the user-space base address of narg null-terminated contiguous
481 * strings.  This is used to read in both the command arguments and
482 * environment strings.  Read at most maxcnt characters of strings.
483 */
484static char **
485kvm_argv(kd, kp, addr, narg, maxcnt)
486	kvm_t *kd;
487	struct kinfo_proc *kp;
488	register u_long addr;
489	register int narg;
490	register int maxcnt;
491{
492	register char *np, *cp, *ep, *ap;
493	register u_long oaddr = -1;
494	register int len, cc;
495	register char **argv;
496
497	/*
498	 * Check that there aren't an unreasonable number of agruments,
499	 * and that the address is in user space.
500	 */
501	if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
502		return (0);
503
504	/*
505	 * kd->argv : work space for fetching the strings from the target
506	 *            process's space, and is converted for returning to caller
507	 */
508	if (kd->argv == 0) {
509		/*
510		 * Try to avoid reallocs.
511		 */
512		kd->argc = MAX(narg + 1, 32);
513		kd->argv = (char **)_kvm_malloc(kd, kd->argc *
514						sizeof(*kd->argv));
515		if (kd->argv == 0)
516			return (0);
517	} else if (narg + 1 > kd->argc) {
518		kd->argc = MAX(2 * kd->argc, narg + 1);
519		kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
520						sizeof(*kd->argv));
521		if (kd->argv == 0)
522			return (0);
523	}
524	/*
525	 * kd->argspc : returned to user, this is where the kd->argv
526	 *              arrays are left pointing to the collected strings.
527	 */
528	if (kd->argspc == 0) {
529		kd->argspc = (char *)_kvm_malloc(kd, PAGE_SIZE);
530		if (kd->argspc == 0)
531			return (0);
532		kd->arglen = PAGE_SIZE;
533	}
534	/*
535	 * kd->argbuf : used to pull in pages from the target process.
536	 *              the strings are copied out of here.
537	 */
538	if (kd->argbuf == 0) {
539		kd->argbuf = (char *)_kvm_malloc(kd, PAGE_SIZE);
540		if (kd->argbuf == 0)
541			return (0);
542	}
543
544	/* Pull in the target process'es argv vector */
545	cc = sizeof(char *) * narg;
546	if (kvm_uread(kd, kp, addr, (char *)kd->argv, cc) != cc)
547		return (0);
548	/*
549	 * ap : saved start address of string we're working on in kd->argspc
550	 * np : pointer to next place to write in kd->argspc
551	 * len: length of data in kd->argspc
552	 * argv: pointer to the argv vector that we are hunting around the
553	 *       target process space for, and converting to addresses in
554	 *       our address space (kd->argspc).
555	 */
556	ap = np = kd->argspc;
557	argv = kd->argv;
558	len = 0;
559	/*
560	 * Loop over pages, filling in the argument vector.
561	 * Note that the argv strings could be pointing *anywhere* in
562	 * the user address space and are no longer contiguous.
563	 * Note that *argv is modified when we are going to fetch a string
564	 * that crosses a page boundary.  We copy the next part of the string
565	 * into to "np" and eventually convert the pointer.
566	 */
567	while (argv < kd->argv + narg && *argv != 0) {
568
569		/* get the address that the current argv string is on */
570		addr = (u_long)*argv & ~(PAGE_SIZE - 1);
571
572		/* is it the same page as the last one? */
573		if (addr != oaddr) {
574			if (kvm_uread(kd, kp, addr, kd->argbuf, PAGE_SIZE) !=
575			    PAGE_SIZE)
576				return (0);
577			oaddr = addr;
578		}
579
580		/* offset within the page... kd->argbuf */
581		addr = (u_long)*argv & (PAGE_SIZE - 1);
582
583		/* cp = start of string, cc = count of chars in this chunk */
584		cp = kd->argbuf + addr;
585		cc = PAGE_SIZE - addr;
586
587		/* dont get more than asked for by user process */
588		if (maxcnt > 0 && cc > maxcnt - len)
589			cc = maxcnt - len;
590
591		/* pointer to end of string if we found it in this page */
592		ep = memchr(cp, '\0', cc);
593		if (ep != 0)
594			cc = ep - cp + 1;
595		/*
596		 * at this point, cc is the count of the chars that we are
597		 * going to retrieve this time. we may or may not have found
598		 * the end of it.  (ep points to the null if the end is known)
599		 */
600
601		/* will we exceed the malloc/realloced buffer? */
602		if (len + cc > kd->arglen) {
603			register int off;
604			register char **pp;
605			register char *op = kd->argspc;
606
607			kd->arglen *= 2;
608			kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
609							  kd->arglen);
610			if (kd->argspc == 0)
611				return (0);
612			/*
613			 * Adjust argv pointers in case realloc moved
614			 * the string space.
615			 */
616			off = kd->argspc - op;
617			for (pp = kd->argv; pp < argv; pp++)
618				*pp += off;
619			ap += off;
620			np += off;
621		}
622		/* np = where to put the next part of the string in kd->argspc*/
623		/* np is kinda redundant.. could use "kd->argspc + len" */
624		memcpy(np, cp, cc);
625		np += cc;	/* inc counters */
626		len += cc;
627
628		/*
629		 * if end of string found, set the *argv pointer to the
630		 * saved beginning of string, and advance. argv points to
631		 * somewhere in kd->argv..  This is initially relative
632		 * to the target process, but when we close it off, we set
633		 * it to point in our address space.
634		 */
635		if (ep != 0) {
636			*argv++ = ap;
637			ap = np;
638		} else {
639			/* update the address relative to the target process */
640			*argv += cc;
641		}
642
643		if (maxcnt > 0 && len >= maxcnt) {
644			/*
645			 * We're stopping prematurely.  Terminate the
646			 * current string.
647			 */
648			if (ep == 0) {
649				*np = '\0';
650				*argv++ = ap;
651			}
652			break;
653		}
654	}
655	/* Make sure argv is terminated. */
656	*argv = 0;
657	return (kd->argv);
658}
659
660static void
661ps_str_a(p, addr, n)
662	struct ps_strings *p;
663	u_long *addr;
664	int *n;
665{
666	*addr = (u_long)p->ps_argvstr;
667	*n = p->ps_nargvstr;
668}
669
670static void
671ps_str_e(p, addr, n)
672	struct ps_strings *p;
673	u_long *addr;
674	int *n;
675{
676	*addr = (u_long)p->ps_envstr;
677	*n = p->ps_nenvstr;
678}
679
680/*
681 * Determine if the proc indicated by p is still active.
682 * This test is not 100% foolproof in theory, but chances of
683 * being wrong are very low.
684 */
685static int
686proc_verify(curkp)
687	struct kinfo_proc *curkp;
688{
689	struct kinfo_proc newkp;
690	int mib[4];
691	size_t len;
692
693	mib[0] = CTL_KERN;
694	mib[1] = KERN_PROC;
695	mib[2] = KERN_PROC_PID;
696	mib[3] = curkp->ki_pid;
697	len = sizeof(newkp);
698	if (sysctl(mib, 4, &newkp, &len, NULL, 0) == -1)
699		return (0);
700	return (curkp->ki_pid == newkp.ki_pid &&
701	    (newkp.ki_stat != SZOMB || curkp->ki_stat == SZOMB));
702}
703
704static char **
705kvm_doargv(kd, kp, nchr, info)
706	kvm_t *kd;
707	struct kinfo_proc *kp;
708	int nchr;
709	void (*info)(struct ps_strings *, u_long *, int *);
710{
711	char **ap;
712	u_long addr;
713	int cnt;
714	static struct ps_strings arginfo;
715	static u_long ps_strings;
716	size_t len;
717
718	if (ps_strings == NULL) {
719		len = sizeof(ps_strings);
720		if (sysctlbyname("kern.ps_strings", &ps_strings, &len, NULL,
721		    0) == -1)
722			ps_strings = PS_STRINGS;
723	}
724
725	/*
726	 * Pointers are stored at the top of the user stack.
727	 */
728	if (kp->ki_stat == SZOMB ||
729	    kvm_uread(kd, kp, ps_strings, (char *)&arginfo,
730		      sizeof(arginfo)) != sizeof(arginfo))
731		return (0);
732
733	(*info)(&arginfo, &addr, &cnt);
734	if (cnt == 0)
735		return (0);
736	ap = kvm_argv(kd, kp, addr, cnt, nchr);
737	/*
738	 * For live kernels, make sure this process didn't go away.
739	 */
740	if (ap != 0 && ISALIVE(kd) && !proc_verify(kp))
741		ap = 0;
742	return (ap);
743}
744
745/*
746 * Get the command args.  This code is now machine independent.
747 */
748char **
749kvm_getargv(kd, kp, nchr)
750	kvm_t *kd;
751	const struct kinfo_proc *kp;
752	int nchr;
753{
754	int oid[4];
755	int i;
756	size_t bufsz;
757	static int buflen;
758	static char *buf, *p;
759	static char **bufp;
760	static int argc;
761
762	if (!ISALIVE(kd)) {
763		_kvm_err(kd, kd->program,
764		    "cannot read user space from dead kernel");
765		return (0);
766	}
767
768	if (!buflen) {
769		bufsz = sizeof(buflen);
770		i = sysctlbyname("kern.ps_arg_cache_limit",
771		    &buflen, &bufsz, NULL, 0);
772		if (i == -1) {
773			buflen = 0;
774		} else {
775			buf = malloc(buflen);
776			if (buf == NULL)
777				buflen = 0;
778			argc = 32;
779			bufp = malloc(sizeof(char *) * argc);
780		}
781	}
782	if (buf != NULL) {
783		oid[0] = CTL_KERN;
784		oid[1] = KERN_PROC;
785		oid[2] = KERN_PROC_ARGS;
786		oid[3] = kp->ki_pid;
787		bufsz = buflen;
788		i = sysctl(oid, 4, buf, &bufsz, 0, 0);
789		if (i == 0 && bufsz > 0) {
790			i = 0;
791			p = buf;
792			do {
793				bufp[i++] = p;
794				p += strlen(p) + 1;
795				if (i >= argc) {
796					argc += argc;
797					bufp = realloc(bufp,
798					    sizeof(char *) * argc);
799				}
800			} while (p < buf + bufsz);
801			bufp[i++] = 0;
802			return (bufp);
803		}
804	}
805	if (kp->ki_flag & P_SYSTEM)
806		return (NULL);
807	return (kvm_doargv(kd, kp, nchr, ps_str_a));
808}
809
810char **
811kvm_getenvv(kd, kp, nchr)
812	kvm_t *kd;
813	const struct kinfo_proc *kp;
814	int nchr;
815{
816	return (kvm_doargv(kd, kp, nchr, ps_str_e));
817}
818
819/*
820 * Read from user space.  The user context is given by p.
821 */
822ssize_t
823kvm_uread(kd, kp, uva, buf, len)
824	kvm_t *kd;
825	struct kinfo_proc *kp;
826	register u_long uva;
827	register char *buf;
828	register size_t len;
829{
830	register char *cp;
831	char procfile[MAXPATHLEN];
832	ssize_t amount;
833	int fd;
834
835	if (!ISALIVE(kd)) {
836		_kvm_err(kd, kd->program,
837		    "cannot read user space from dead kernel");
838		return (0);
839	}
840
841	sprintf(procfile, "/proc/%d/mem", kp->ki_pid);
842	fd = open(procfile, O_RDONLY, 0);
843	if (fd < 0) {
844		_kvm_err(kd, kd->program, "cannot open %s", procfile);
845		close(fd);
846		return (0);
847	}
848
849	cp = buf;
850	while (len > 0) {
851		errno = 0;
852		if (lseek(fd, (off_t)uva, 0) == -1 && errno != 0) {
853			_kvm_err(kd, kd->program, "invalid address (%x) in %s",
854			    uva, procfile);
855			break;
856		}
857		amount = read(fd, cp, len);
858		if (amount < 0) {
859			_kvm_syserr(kd, kd->program, "error reading %s",
860			    procfile);
861			break;
862		}
863		if (amount == 0) {
864			_kvm_err(kd, kd->program, "EOF reading %s", procfile);
865			break;
866		}
867		cp += amount;
868		uva += amount;
869		len -= amount;
870	}
871
872	close(fd);
873	return ((ssize_t)(cp - buf));
874}
875