1 /* $NetBSD: kvm_proc.c,v 1.83 2009/05/16 11:56:47 yamt Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1989, 1992, 1993
34 * The Regents of the University of California. All rights reserved.
36 * This code is derived from software developed by the Computer Systems
37 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
38 * BG 91-66 and contributed to Berkeley.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 #include <sys/cdefs.h>
66 #if defined(LIBC_SCCS) && !defined(lint)
68 static char sccsid
[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93";
70 __RCSID("$NetBSD: kvm_proc.c,v 1.83 2009/05/16 11:56:47 yamt Exp $");
72 #endif /* LIBC_SCCS and not lint */
75 * Proc traversal interface for kvm. ps and w are (probably) the exclusive
76 * users of this code, so we've factored it out into a separate module.
77 * Thus, we keep this grunge out of the other kvm applications (i.e.,
78 * most other applications are interested only in open/close/read/nlist).
81 #include <sys/param.h>
87 #include <sys/ioctl.h>
89 #include <sys/resourcevar.h>
90 #include <sys/mutex.h>
91 #include <sys/specificdata.h>
101 #include <uvm/uvm_extern.h>
102 #include <uvm/uvm_param.h>
103 #include <uvm/uvm_amap.h>
105 #include <sys/sysctl.h>
111 #include "kvm_private.h"
114 * Common info from kinfo_proc and kinfo_proc2 used by helper routines.
117 struct vmspace
*p_vmspace
;
119 struct proc
*p_paddr
;
124 * Convert from struct proc and kinfo_proc{,2} to miniproc.
126 #define PTOMINI(kp, p) \
128 (p)->p_stat = (kp)->p_stat; \
129 (p)->p_pid = (kp)->p_pid; \
130 (p)->p_paddr = NULL; \
131 (p)->p_vmspace = (kp)->p_vmspace; \
132 } while (/*CONSTCOND*/0);
134 #define KPTOMINI(kp, p) \
136 (p)->p_stat = (kp)->kp_proc.p_stat; \
137 (p)->p_pid = (kp)->kp_proc.p_pid; \
138 (p)->p_paddr = (kp)->kp_eproc.e_paddr; \
139 (p)->p_vmspace = (kp)->kp_proc.p_vmspace; \
140 } while (/*CONSTCOND*/0);
142 #define KP2TOMINI(kp, p) \
144 (p)->p_stat = (kp)->p_stat; \
145 (p)->p_pid = (kp)->p_pid; \
146 (p)->p_paddr = (void *)(long)(kp)->p_paddr; \
147 (p)->p_vmspace = (void *)(long)(kp)->p_vmspace; \
148 } while (/*CONSTCOND*/0);
151 * NetBSD uses kauth(9) to manage credentials, which are stored in kauth_cred_t,
152 * a kernel-only opaque type. This is an embedded version which is *INTERNAL* to
153 * kvm(3) so dumps can be read properly.
155 * Whenever NetBSD starts exporting credentials to userland consistently (using
156 * 'struct uucred', or something) this will have to be updated again.
158 struct kvm_kauth_cred
{
159 u_int cr_refcnt
; /* reference count */
160 uint8_t cr_pad
[CACHE_LINE_SIZE
- sizeof(u_int
)];
161 uid_t cr_uid
; /* user id */
162 uid_t cr_euid
; /* effective user id */
163 uid_t cr_svuid
; /* saved effective user id */
164 gid_t cr_gid
; /* group id */
165 gid_t cr_egid
; /* effective group id */
166 gid_t cr_svgid
; /* saved effective group id */
167 u_int cr_ngroups
; /* number of groups */
168 gid_t cr_groups
[NGROUPS
]; /* group memberships */
169 specificdata_reference cr_sd
; /* specific data */
172 #define KREAD(kd, addr, obj) \
173 (kvm_read(kd, addr, (obj), sizeof(*obj)) != sizeof(*obj))
175 /* XXX: What uses these two functions? */
176 char *_kvm_uread
__P((kvm_t
*, const struct proc
*, u_long
,
178 ssize_t kvm_uread
__P((kvm_t
*, const struct proc
*, u_long
, char *,
181 static char *_kvm_ureadm
__P((kvm_t
*, const struct miniproc
*, u_long
,
183 static ssize_t kvm_ureadm
__P((kvm_t
*, const struct miniproc
*, u_long
,
186 static char **kvm_argv
__P((kvm_t
*, const struct miniproc
*, u_long
, int,
188 static int kvm_deadprocs
__P((kvm_t
*, int, int, u_long
, u_long
, int));
189 static char **kvm_doargv
__P((kvm_t
*, const struct miniproc
*, int,
190 void (*)(struct ps_strings
*, u_long
*, int *)));
191 static char **kvm_doargv2
__P((kvm_t
*, pid_t
, int, int));
192 static int kvm_proclist
__P((kvm_t
*, int, int, struct proc
*,
193 struct kinfo_proc
*, int));
194 static int proc_verify
__P((kvm_t
*, u_long
, const struct miniproc
*));
195 static void ps_str_a
__P((struct ps_strings
*, u_long
*, int *));
196 static void ps_str_e
__P((struct ps_strings
*, u_long
*, int *));
200 _kvm_ureadm(kd
, p
, va
, cnt
)
202 const struct miniproc
*p
;
208 struct vm_map_entry vme
;
210 struct vm_anon
*anonp
, anon
;
214 if (kd
->swapspc
== NULL
) {
215 kd
->swapspc
= _kvm_malloc(kd
, (size_t)kd
->nbpg
);
216 if (kd
->swapspc
== NULL
)
221 * Look through the address map for the memory object
222 * that corresponds to the given virtual address.
223 * The header just has the entire valid range.
225 head
= (u_long
)&p
->p_vmspace
->vm_map
.header
;
228 if (KREAD(kd
, addr
, &vme
))
231 if (va
>= vme
.start
&& va
< vme
.end
&&
232 vme
.aref
.ar_amap
!= NULL
)
235 addr
= (u_long
)vme
.next
;
241 * we found the map entry, now to find the object...
243 if (vme
.aref
.ar_amap
== NULL
)
246 addr
= (u_long
)vme
.aref
.ar_amap
;
247 if (KREAD(kd
, addr
, &amap
))
250 offset
= va
- vme
.start
;
251 slot
= offset
/ kd
->nbpg
+ vme
.aref
.ar_pageoff
;
252 /* sanity-check slot number */
253 if (slot
> amap
.am_nslot
)
256 addr
= (u_long
)amap
.am_anon
+ (offset
/ kd
->nbpg
) * sizeof(anonp
);
257 if (KREAD(kd
, addr
, &anonp
))
260 addr
= (u_long
)anonp
;
261 if (KREAD(kd
, addr
, &anon
))
264 addr
= (u_long
)anon
.an_page
;
266 if (KREAD(kd
, addr
, &pg
))
269 if (_kvm_pread(kd
, kd
->pmfd
, kd
->swapspc
, (size_t)kd
->nbpg
,
270 (off_t
)pg
.phys_addr
) != kd
->nbpg
)
274 _kvm_pread(kd
, kd
->swfd
, kd
->swapspc
, (size_t)kd
->nbpg
,
275 (off_t
)(anon
.an_swslot
* kd
->nbpg
)) != kd
->nbpg
)
279 /* Found the page. */
281 *cnt
= kd
->nbpg
- offset
;
282 return (&kd
->swapspc
[(size_t)offset
]);
286 _kvm_uread(kd
, p
, va
, cnt
)
288 const struct proc
*p
;
295 return (_kvm_ureadm(kd
, &mp
, va
, cnt
));
299 * Convert credentials located in kernel space address 'cred' and store
300 * them in the appropriate members of 'eproc'.
303 _kvm_convertcred(kvm_t
*kd
, u_long cred
, struct eproc
*eproc
)
305 struct kvm_kauth_cred kauthcred
;
306 struct ki_pcred
*pc
= &eproc
->e_pcred
;
307 struct ki_ucred
*uc
= &eproc
->e_ucred
;
309 if (KREAD(kd
, cred
, &kauthcred
) != 0)
312 /* inlined version of kauth_cred_to_pcred, see kauth(9). */
313 pc
->p_ruid
= kauthcred
.cr_uid
;
314 pc
->p_svuid
= kauthcred
.cr_svuid
;
315 pc
->p_rgid
= kauthcred
.cr_gid
;
316 pc
->p_svgid
= kauthcred
.cr_svgid
;
317 pc
->p_refcnt
= kauthcred
.cr_refcnt
;
320 /* inlined version of kauth_cred_to_ucred(), see kauth(9). */
321 uc
->cr_ref
= kauthcred
.cr_refcnt
;
322 uc
->cr_uid
= kauthcred
.cr_euid
;
323 uc
->cr_gid
= kauthcred
.cr_egid
;
324 uc
->cr_ngroups
= (uint32_t)MIN(kauthcred
.cr_ngroups
,
325 sizeof(uc
->cr_groups
) / sizeof(uc
->cr_groups
[0]));
326 memcpy(uc
->cr_groups
, kauthcred
.cr_groups
,
327 uc
->cr_ngroups
* sizeof(uc
->cr_groups
[0]));
333 * Read proc's from memory file into buffer bp, which has space to hold
334 * at most maxcnt procs.
337 kvm_proclist(kd
, what
, arg
, p
, bp
, maxcnt
)
341 struct kinfo_proc
*bp
;
346 struct kinfo_lwp
*kl
;
353 for (; cnt
< maxcnt
&& p
!= NULL
; p
= proc
.p_list
.le_next
) {
354 if (KREAD(kd
, (u_long
)p
, &proc
)) {
355 _kvm_err(kd
, kd
->program
, "can't read proc at %p", p
);
358 if (_kvm_convertcred(kd
, (u_long
)proc
.p_cred
, &eproc
) != 0) {
359 _kvm_err(kd
, kd
->program
,
360 "can't read proc credentials at %p", p
);
367 if (proc
.p_pid
!= (pid_t
)arg
)
372 if (eproc
.e_ucred
.cr_uid
!= (uid_t
)arg
)
377 if (eproc
.e_pcred
.p_ruid
!= (uid_t
)arg
)
382 * We're going to add another proc to the set. If this
383 * will overflow the buffer, assume the reason is because
384 * nprocs (or the proc list) is corrupt and declare an error.
387 _kvm_err(kd
, kd
->program
, "nprocs corrupt");
394 if (KREAD(kd
, (u_long
)proc
.p_pgrp
, &pgrp
)) {
395 _kvm_err(kd
, kd
->program
, "can't read pgrp at %p",
399 eproc
.e_sess
= pgrp
.pg_session
;
400 eproc
.e_pgid
= pgrp
.pg_id
;
401 eproc
.e_jobc
= pgrp
.pg_jobc
;
402 if (KREAD(kd
, (u_long
)pgrp
.pg_session
, &sess
)) {
403 _kvm_err(kd
, kd
->program
, "can't read session at %p",
407 if ((proc
.p_lflag
& PL_CONTROLT
) && sess
.s_ttyp
!= NULL
) {
408 if (KREAD(kd
, (u_long
)sess
.s_ttyp
, &tty
)) {
409 _kvm_err(kd
, kd
->program
,
410 "can't read tty at %p", sess
.s_ttyp
);
413 eproc
.e_tdev
= (uint32_t)tty
.t_dev
;
414 eproc
.e_tsess
= tty
.t_session
;
415 if (tty
.t_pgrp
!= NULL
) {
416 if (KREAD(kd
, (u_long
)tty
.t_pgrp
, &pgrp
)) {
417 _kvm_err(kd
, kd
->program
,
418 "can't read tpgrp at %p",
422 eproc
.e_tpgid
= pgrp
.pg_id
;
426 eproc
.e_tdev
= (uint32_t)NODEV
;
427 eproc
.e_flag
= sess
.s_ttyvp
? EPROC_CTTY
: 0;
428 eproc
.e_sid
= sess
.s_sid
;
429 if (sess
.s_leader
== p
)
430 eproc
.e_flag
|= EPROC_SLEADER
;
432 * Fill in the old-style proc.p_wmesg by copying the wmesg
433 * from the first available LWP.
435 kl
= kvm_getlwps(kd
, proc
.p_pid
,
436 (u_long
)PTRTOUINT64(eproc
.e_paddr
),
437 sizeof(struct kinfo_lwp
), &nlwps
);
440 strcpy(eproc
.e_wmesg
, kl
[0].l_wmesg
);
443 (void)kvm_read(kd
, (u_long
)proc
.p_vmspace
, &eproc
.e_vm
,
446 eproc
.e_xsize
= eproc
.e_xrssize
= 0;
447 eproc
.e_xccount
= eproc
.e_xswrss
= 0;
452 if (eproc
.e_pgid
!= (pid_t
)arg
)
457 if ((proc
.p_lflag
& PL_CONTROLT
) == 0 ||
458 eproc
.e_tdev
!= (dev_t
)arg
)
462 memcpy(&bp
->kp_proc
, &proc
, sizeof(proc
));
463 memcpy(&bp
->kp_eproc
, &eproc
, sizeof(eproc
));
471 * Build proc info array by reading in proc list from a crash dump.
472 * Return number of procs read. maxcnt is the max we will read.
475 kvm_deadprocs(kd
, what
, arg
, a_allproc
, a_zombproc
, maxcnt
)
482 struct kinfo_proc
*bp
= kd
->procbase
;
486 if (KREAD(kd
, a_allproc
, &p
)) {
487 _kvm_err(kd
, kd
->program
, "cannot read allproc");
490 acnt
= kvm_proclist(kd
, what
, arg
, p
, bp
, maxcnt
);
494 if (KREAD(kd
, a_zombproc
, &p
)) {
495 _kvm_err(kd
, kd
->program
, "cannot read zombproc");
498 zcnt
= kvm_proclist(kd
, what
, arg
, p
, bp
+ acnt
,
503 return (acnt
+ zcnt
);
507 kvm_getproc2(kd
, op
, arg
, esize
, cnt
)
514 int mib
[6], st
, nprocs
;
515 struct pstats pstats
;
526 st
= sysctl(mib
, 6, NULL
, &size
, NULL
, (size_t)0);
528 _kvm_syserr(kd
, kd
->program
, "kvm_getproc2");
532 mib
[5] = (int) (size
/ esize
);
533 KVM_ALLOC(kd
, procbase2
, size
);
534 st
= sysctl(mib
, 6, kd
->procbase2
, &size
, NULL
, (size_t)0);
536 if (errno
== ENOMEM
) {
539 _kvm_syserr(kd
, kd
->program
, "kvm_getproc2");
542 nprocs
= (int) (size
/ esize
);
545 struct kinfo_proc
*kp
;
546 struct kinfo_proc2 kp2
, *kp2p
;
547 struct kinfo_lwp
*kl
;
550 kp
= kvm_getprocs(kd
, op
, arg
, &nprocs
);
554 size
= nprocs
* esize
;
555 KVM_ALLOC(kd
, procbase2
, size
);
556 kp2c
= (char *)(void *)kd
->procbase2
;
558 for (i
= 0; i
< nprocs
; i
++, kp
++) {
561 kl
= kvm_getlwps(kd
, kp
->kp_proc
.p_pid
,
562 (u_long
)PTRTOUINT64(kp
->kp_eproc
.e_paddr
),
563 sizeof(struct kinfo_lwp
), &nlwps
);
566 _kvm_syserr(kd
, NULL
,
567 "kvm_getlwps() failed on process %u\n",
575 /* We use kl[0] as the "representative" LWP */
576 memset(kp2p
, 0, sizeof(kp2
));
577 kp2p
->p_forw
= kl
[0].l_forw
;
578 kp2p
->p_back
= kl
[0].l_back
;
579 kp2p
->p_paddr
= PTRTOUINT64(kp
->kp_eproc
.e_paddr
);
580 kp2p
->p_addr
= kl
[0].l_addr
;
581 kp2p
->p_fd
= PTRTOUINT64(kp
->kp_proc
.p_fd
);
582 kp2p
->p_cwdi
= PTRTOUINT64(kp
->kp_proc
.p_cwdi
);
583 kp2p
->p_stats
= PTRTOUINT64(kp
->kp_proc
.p_stats
);
584 kp2p
->p_limit
= PTRTOUINT64(kp
->kp_proc
.p_limit
);
585 kp2p
->p_vmspace
= PTRTOUINT64(kp
->kp_proc
.p_vmspace
);
586 kp2p
->p_sigacts
= PTRTOUINT64(kp
->kp_proc
.p_sigacts
);
587 kp2p
->p_sess
= PTRTOUINT64(kp
->kp_eproc
.e_sess
);
589 #if 1 /* XXX: dsl - p_ru was only ever non-zero for zombies */
592 kp2p
->p_ru
= PTRTOUINT64(pstats
.p_ru
);
596 kp2p
->p_exitsig
= kp
->kp_proc
.p_exitsig
;
597 kp2p
->p_flag
= kp
->kp_proc
.p_flag
;
599 kp2p
->p_pid
= kp
->kp_proc
.p_pid
;
601 kp2p
->p_ppid
= kp
->kp_eproc
.e_ppid
;
602 kp2p
->p_sid
= kp
->kp_eproc
.e_sid
;
603 kp2p
->p__pgid
= kp
->kp_eproc
.e_pgid
;
605 kp2p
->p_tpgid
= -1 /* XXX NO_PGID! */;
607 kp2p
->p_uid
= kp
->kp_eproc
.e_ucred
.cr_uid
;
608 kp2p
->p_ruid
= kp
->kp_eproc
.e_pcred
.p_ruid
;
609 kp2p
->p_svuid
= kp
->kp_eproc
.e_pcred
.p_svuid
;
610 kp2p
->p_gid
= kp
->kp_eproc
.e_ucred
.cr_gid
;
611 kp2p
->p_rgid
= kp
->kp_eproc
.e_pcred
.p_rgid
;
612 kp2p
->p_svgid
= kp
->kp_eproc
.e_pcred
.p_svgid
;
615 memcpy(kp2p
->p_groups
, kp
->kp_eproc
.e_ucred
.cr_groups
,
616 MIN(sizeof(kp2p
->p_groups
),
617 sizeof(kp
->kp_eproc
.e_ucred
.cr_groups
)));
618 kp2p
->p_ngroups
= kp
->kp_eproc
.e_ucred
.cr_ngroups
;
620 kp2p
->p_jobc
= kp
->kp_eproc
.e_jobc
;
621 kp2p
->p_tdev
= kp
->kp_eproc
.e_tdev
;
622 kp2p
->p_tpgid
= kp
->kp_eproc
.e_tpgid
;
623 kp2p
->p_tsess
= PTRTOUINT64(kp
->kp_eproc
.e_tsess
);
626 bintime2timeval(&kp
->kp_proc
.p_rtime
, &tv
);
627 kp2p
->p_rtime_sec
= (uint32_t)tv
.tv_sec
;
628 kp2p
->p_rtime_usec
= (uint32_t)tv
.tv_usec
;
629 kp2p
->p_cpticks
= kl
[0].l_cpticks
;
630 kp2p
->p_pctcpu
= kp
->kp_proc
.p_pctcpu
;
631 kp2p
->p_swtime
= kl
[0].l_swtime
;
632 kp2p
->p_slptime
= kl
[0].l_slptime
;
633 #if 0 /* XXX thorpej */
634 kp2p
->p_schedflags
= kp
->kp_proc
.p_schedflags
;
636 kp2p
->p_schedflags
= 0;
639 kp2p
->p_uticks
= kp
->kp_proc
.p_uticks
;
640 kp2p
->p_sticks
= kp
->kp_proc
.p_sticks
;
641 kp2p
->p_iticks
= kp
->kp_proc
.p_iticks
;
643 kp2p
->p_tracep
= PTRTOUINT64(kp
->kp_proc
.p_tracep
);
644 kp2p
->p_traceflag
= kp
->kp_proc
.p_traceflag
;
646 kp2p
->p_holdcnt
= kl
[0].l_holdcnt
;
648 memcpy(&kp2p
->p_siglist
,
649 &kp
->kp_proc
.p_sigpend
.sp_set
,
650 sizeof(ki_sigset_t
));
651 memset(&kp2p
->p_sigmask
, 0,
652 sizeof(ki_sigset_t
));
653 memcpy(&kp2p
->p_sigignore
,
654 &kp
->kp_proc
.p_sigctx
.ps_sigignore
,
655 sizeof(ki_sigset_t
));
656 memcpy(&kp2p
->p_sigcatch
,
657 &kp
->kp_proc
.p_sigctx
.ps_sigcatch
,
658 sizeof(ki_sigset_t
));
660 kp2p
->p_stat
= kl
[0].l_stat
;
661 kp2p
->p_priority
= kl
[0].l_priority
;
662 kp2p
->p_usrpri
= kl
[0].l_priority
;
663 kp2p
->p_nice
= kp
->kp_proc
.p_nice
;
665 kp2p
->p_xstat
= kp
->kp_proc
.p_xstat
;
666 kp2p
->p_acflag
= kp
->kp_proc
.p_acflag
;
669 strncpy(kp2p
->p_comm
, kp
->kp_proc
.p_comm
,
670 MIN(sizeof(kp2p
->p_comm
),
671 sizeof(kp
->kp_proc
.p_comm
)));
673 strncpy(kp2p
->p_wmesg
, kp
->kp_eproc
.e_wmesg
,
674 sizeof(kp2p
->p_wmesg
));
675 kp2p
->p_wchan
= kl
[0].l_wchan
;
676 strncpy(kp2p
->p_login
, kp
->kp_eproc
.e_login
,
677 sizeof(kp2p
->p_login
));
679 kp2p
->p_vm_rssize
= kp
->kp_eproc
.e_xrssize
;
680 kp2p
->p_vm_tsize
= kp
->kp_eproc
.e_vm
.vm_tsize
;
681 kp2p
->p_vm_dsize
= kp
->kp_eproc
.e_vm
.vm_dsize
;
682 kp2p
->p_vm_ssize
= kp
->kp_eproc
.e_vm
.vm_ssize
;
683 kp2p
->p_vm_vsize
= kp
->kp_eproc
.e_vm
.vm_map
.size
;
684 /* Adjust mapped size */
686 (kp
->kp_eproc
.e_vm
.vm_map
.size
/ kd
->nbpg
) -
687 kp
->kp_eproc
.e_vm
.vm_issize
+
688 kp
->kp_eproc
.e_vm
.vm_ssize
;
690 kp2p
->p_eflag
= (int32_t)kp
->kp_eproc
.e_flag
;
692 kp2p
->p_realflag
= kp
->kp_proc
.p_flag
;
693 kp2p
->p_nlwps
= kp
->kp_proc
.p_nlwps
;
694 kp2p
->p_nrlwps
= kp
->kp_proc
.p_nrlwps
;
695 kp2p
->p_realstat
= kp
->kp_proc
.p_stat
;
697 if (P_ZOMBIE(&kp
->kp_proc
) ||
698 kp
->kp_proc
.p_stats
== NULL
||
699 KREAD(kd
, (u_long
)kp
->kp_proc
.p_stats
, &pstats
)) {
704 kp2p
->p_ustart_sec
= (u_int32_t
)
705 pstats
.p_start
.tv_sec
;
706 kp2p
->p_ustart_usec
= (u_int32_t
)
707 pstats
.p_start
.tv_usec
;
709 kp2p
->p_uutime_sec
= (u_int32_t
)
710 pstats
.p_ru
.ru_utime
.tv_sec
;
711 kp2p
->p_uutime_usec
= (u_int32_t
)
712 pstats
.p_ru
.ru_utime
.tv_usec
;
713 kp2p
->p_ustime_sec
= (u_int32_t
)
714 pstats
.p_ru
.ru_stime
.tv_sec
;
715 kp2p
->p_ustime_usec
= (u_int32_t
)
716 pstats
.p_ru
.ru_stime
.tv_usec
;
718 kp2p
->p_uru_maxrss
= pstats
.p_ru
.ru_maxrss
;
719 kp2p
->p_uru_ixrss
= pstats
.p_ru
.ru_ixrss
;
720 kp2p
->p_uru_idrss
= pstats
.p_ru
.ru_idrss
;
721 kp2p
->p_uru_isrss
= pstats
.p_ru
.ru_isrss
;
722 kp2p
->p_uru_minflt
= pstats
.p_ru
.ru_minflt
;
723 kp2p
->p_uru_majflt
= pstats
.p_ru
.ru_majflt
;
724 kp2p
->p_uru_nswap
= pstats
.p_ru
.ru_nswap
;
725 kp2p
->p_uru_inblock
= pstats
.p_ru
.ru_inblock
;
726 kp2p
->p_uru_oublock
= pstats
.p_ru
.ru_oublock
;
727 kp2p
->p_uru_msgsnd
= pstats
.p_ru
.ru_msgsnd
;
728 kp2p
->p_uru_msgrcv
= pstats
.p_ru
.ru_msgrcv
;
729 kp2p
->p_uru_nsignals
= pstats
.p_ru
.ru_nsignals
;
730 kp2p
->p_uru_nvcsw
= pstats
.p_ru
.ru_nvcsw
;
731 kp2p
->p_uru_nivcsw
= pstats
.p_ru
.ru_nivcsw
;
733 kp2p
->p_uctime_sec
= (u_int32_t
)
734 (pstats
.p_cru
.ru_utime
.tv_sec
+
735 pstats
.p_cru
.ru_stime
.tv_sec
);
736 kp2p
->p_uctime_usec
= (u_int32_t
)
737 (pstats
.p_cru
.ru_utime
.tv_usec
+
738 pstats
.p_cru
.ru_stime
.tv_usec
);
741 memcpy(kp2c
, &kp2
, esize
);
746 return (kd
->procbase2
);
750 kvm_getlwps(kd
, pid
, paddr
, esize
, cnt
)
760 struct kinfo_lwp
*kl
;
770 st
= sysctl(mib
, 5, NULL
, &size
, NULL
, (size_t)0);
773 case ESRCH
: /* Treat this as a soft error; see kvm.c */
774 _kvm_syserr(kd
, NULL
, "kvm_getlwps");
777 _kvm_syserr(kd
, kd
->program
, "kvm_getlwps");
781 mib
[4] = (int) (size
/ esize
);
782 KVM_ALLOC(kd
, lwpbase
, size
);
783 st
= sysctl(mib
, 5, kd
->lwpbase
, &size
, NULL
, (size_t)0);
786 case ESRCH
: /* Treat this as a soft error; see kvm.c */
787 _kvm_syserr(kd
, NULL
, "kvm_getlwps");
792 _kvm_syserr(kd
, kd
->program
, "kvm_getlwps");
796 nlwps
= (int) (size
/ esize
);
798 /* grovel through the memory image */
805 st
= kvm_read(kd
, paddr
, &p
, sizeof(p
));
807 _kvm_syserr(kd
, kd
->program
, "kvm_getlwps");
812 size
= nlwps
* sizeof(*kd
->lwpbase
);
813 KVM_ALLOC(kd
, lwpbase
, size
);
814 laddr
= (u_long
)PTRTOUINT64(p
.p_lwps
.lh_first
);
815 for (i
= 0; (i
< nlwps
) && (laddr
!= 0); i
++) {
816 st
= kvm_read(kd
, laddr
, &l
, sizeof(l
));
818 _kvm_syserr(kd
, kd
->program
, "kvm_getlwps");
821 kl
= &kd
->lwpbase
[i
];
823 kl
->l_forw
= PTRTOUINT64(l
.l_runq
.tqe_next
);
824 laddr
= (u_long
)PTRTOUINT64(l
.l_runq
.tqe_prev
);
825 st
= kvm_read(kd
, laddr
, &back
, sizeof(back
));
827 _kvm_syserr(kd
, kd
->program
, "kvm_getlwps");
830 kl
->l_back
= PTRTOUINT64(back
);
831 kl
->l_addr
= PTRTOUINT64(l
.l_addr
);
833 kl
->l_flag
= l
.l_flag
;
834 kl
->l_swtime
= l
.l_swtime
;
835 kl
->l_slptime
= l
.l_slptime
;
836 kl
->l_schedflags
= 0; /* XXX */
838 kl
->l_priority
= l
.l_priority
;
839 kl
->l_usrpri
= l
.l_priority
;
840 kl
->l_stat
= l
.l_stat
;
841 kl
->l_wchan
= PTRTOUINT64(l
.l_wchan
);
843 (void)kvm_read(kd
, (u_long
)l
.l_wmesg
,
844 kl
->l_wmesg
, (size_t)WMESGLEN
);
845 kl
->l_cpuid
= KI_NOCPU
;
846 laddr
= (u_long
)PTRTOUINT64(l
.l_sibling
.le_next
);
851 return (kd
->lwpbase
);
855 kvm_getprocs(kd
, op
, arg
, cnt
)
861 int mib
[4], st
, nprocs
;
869 st
= sysctl(mib
, 4, NULL
, &size
, NULL
, (size_t)0);
871 _kvm_syserr(kd
, kd
->program
, "kvm_getprocs");
874 KVM_ALLOC(kd
, procbase
, size
);
875 st
= sysctl(mib
, 4, kd
->procbase
, &size
, NULL
, (size_t)0);
877 _kvm_syserr(kd
, kd
->program
, "kvm_getprocs");
880 if (size
% sizeof(struct kinfo_proc
) != 0) {
881 _kvm_err(kd
, kd
->program
,
882 "proc size mismatch (%lu total, %lu chunks)",
883 (u_long
)size
, (u_long
)sizeof(struct kinfo_proc
));
886 nprocs
= (int) (size
/ sizeof(struct kinfo_proc
));
888 struct nlist nl
[4], *p
;
890 (void)memset(nl
, 0, sizeof(nl
));
891 nl
[0].n_name
= "_nprocs";
892 nl
[1].n_name
= "_allproc";
893 nl
[2].n_name
= "_zombproc";
896 if (kvm_nlist(kd
, nl
) != 0) {
897 for (p
= nl
; p
->n_type
!= 0; ++p
)
899 _kvm_err(kd
, kd
->program
,
900 "%s: no such symbol", p
->n_name
);
903 if (KREAD(kd
, nl
[0].n_value
, &nprocs
)) {
904 _kvm_err(kd
, kd
->program
, "can't read nprocs");
907 size
= nprocs
* sizeof(*kd
->procbase
);
908 KVM_ALLOC(kd
, procbase
, size
);
909 nprocs
= kvm_deadprocs(kd
, op
, arg
, nl
[1].n_value
,
910 nl
[2].n_value
, nprocs
);
914 size
= nprocs
* sizeof(struct kinfo_proc
);
915 (void)realloc(kd
->procbase
, size
);
919 return (kd
->procbase
);
923 _kvm_realloc(kd
, p
, n
)
928 void *np
= realloc(p
, n
);
931 _kvm_err(kd
, kd
->program
, "out of memory");
936 * Read in an argument vector from the user address space of process p.
937 * addr if the user-space base address of narg null-terminated contiguous
938 * strings. This is used to read in both the command arguments and
939 * environment strings. Read at most maxcnt characters of strings.
942 kvm_argv(kd
, p
, addr
, narg
, maxcnt
)
944 const struct miniproc
*p
;
949 char *np
, *cp
, *ep
, *ap
;
950 u_long oaddr
= (u_long
)~0L;
956 * Check that there aren't an unreasonable number of arguments,
957 * and that the address is in user space.
959 if (narg
> ARG_MAX
|| addr
< kd
->min_uva
|| addr
>= kd
->max_uva
)
962 if (kd
->argv
== NULL
) {
964 * Try to avoid reallocs.
966 kd
->argc
= MAX(narg
+ 1, 32);
967 kd
->argv
= _kvm_malloc(kd
, kd
->argc
* sizeof(*kd
->argv
));
968 if (kd
->argv
== NULL
)
970 } else if (narg
+ 1 > kd
->argc
) {
971 kd
->argc
= MAX(2 * kd
->argc
, narg
+ 1);
972 kd
->argv
= _kvm_realloc(kd
, kd
->argv
, kd
->argc
*
974 if (kd
->argv
== NULL
)
977 if (kd
->argspc
== NULL
) {
978 kd
->argspc
= _kvm_malloc(kd
, (size_t)kd
->nbpg
);
979 if (kd
->argspc
== NULL
)
981 kd
->argspc_len
= kd
->nbpg
;
983 if (kd
->argbuf
== NULL
) {
984 kd
->argbuf
= _kvm_malloc(kd
, (size_t)kd
->nbpg
);
985 if (kd
->argbuf
== NULL
)
988 cc
= sizeof(char *) * narg
;
989 if (kvm_ureadm(kd
, p
, addr
, (void *)kd
->argv
, cc
) != cc
)
991 ap
= np
= kd
->argspc
;
995 * Loop over pages, filling in the argument vector.
997 while (argv
< kd
->argv
+ narg
&& *argv
!= NULL
) {
998 addr
= (u_long
)*argv
& ~(kd
->nbpg
- 1);
1000 if (kvm_ureadm(kd
, p
, addr
, kd
->argbuf
,
1001 (size_t)kd
->nbpg
) != kd
->nbpg
)
1005 addr
= (u_long
)*argv
& (kd
->nbpg
- 1);
1006 cp
= kd
->argbuf
+ (size_t)addr
;
1007 cc
= kd
->nbpg
- (size_t)addr
;
1008 if (maxcnt
> 0 && cc
> (size_t)(maxcnt
- len
))
1009 cc
= (size_t)(maxcnt
- len
);
1010 ep
= memchr(cp
, '\0', cc
);
1013 if (len
+ cc
> kd
->argspc_len
) {
1016 char *op
= kd
->argspc
;
1018 kd
->argspc_len
*= 2;
1019 kd
->argspc
= _kvm_realloc(kd
, kd
->argspc
,
1021 if (kd
->argspc
== NULL
)
1024 * Adjust argv pointers in case realloc moved
1027 off
= kd
->argspc
- op
;
1028 for (pp
= kd
->argv
; pp
< argv
; pp
++)
1041 if (maxcnt
> 0 && len
>= maxcnt
) {
1043 * We're stopping prematurely. Terminate the
1053 /* Make sure argv is terminated. */
1059 ps_str_a(p
, addr
, n
)
1060 struct ps_strings
*p
;
1065 *addr
= (u_long
)p
->ps_argvstr
;
1066 *n
= p
->ps_nargvstr
;
1070 ps_str_e(p
, addr
, n
)
1071 struct ps_strings
*p
;
1076 *addr
= (u_long
)p
->ps_envstr
;
1081 * Determine if the proc indicated by p is still active.
1082 * This test is not 100% foolproof in theory, but chances of
1083 * being wrong are very low.
1086 proc_verify(kd
, kernp
, p
)
1089 const struct miniproc
*p
;
1091 struct proc kernproc
;
1094 * Just read in the whole proc. It's not that big relative
1095 * to the cost of the read system call.
1097 if (kvm_read(kd
, kernp
, &kernproc
, sizeof(kernproc
)) !=
1100 return (p
->p_pid
== kernproc
.p_pid
&&
1101 (kernproc
.p_stat
!= SZOMB
|| p
->p_stat
== SZOMB
));
1105 kvm_doargv(kd
, p
, nchr
, info
)
1107 const struct miniproc
*p
;
1109 void (*info
)(struct ps_strings
*, u_long
*, int *);
1114 struct ps_strings arginfo
;
1117 * Pointers are stored at the top of the user stack.
1119 if (p
->p_stat
== SZOMB
)
1121 cnt
= (int)kvm_ureadm(kd
, p
, kd
->usrstack
- sizeof(arginfo
),
1122 (void *)&arginfo
, sizeof(arginfo
));
1123 if (cnt
!= sizeof(arginfo
))
1126 (*info
)(&arginfo
, &addr
, &cnt
);
1129 ap
= kvm_argv(kd
, p
, addr
, cnt
, nchr
);
1131 * For live kernels, make sure this process didn't go away.
1133 if (ap
!= NULL
&& ISALIVE(kd
) &&
1134 !proc_verify(kd
, (u_long
)p
->p_paddr
, p
))
1140 * Get the command args. This code is now machine independent.
1143 kvm_getargv(kd
, kp
, nchr
)
1145 const struct kinfo_proc
*kp
;
1151 return (kvm_doargv(kd
, &p
, nchr
, ps_str_a
));
1155 kvm_getenvv(kd
, kp
, nchr
)
1157 const struct kinfo_proc
*kp
;
1163 return (kvm_doargv(kd
, &p
, nchr
, ps_str_e
));
1167 kvm_doargv2(kd
, pid
, type
, nchr
)
1175 size_t newargspc_len
;
1176 char **ap
, *bp
, *endp
;
1179 * Check that there aren't an unreasonable number of arguments.
1187 /* Get number of strings in argv */
1189 mib
[1] = KERN_PROC_ARGS
;
1191 mib
[3] = type
== KERN_PROC_ARGV
? KERN_PROC_NARGV
: KERN_PROC_NENV
;
1192 bufs
= sizeof(narg
);
1193 if (sysctl(mib
, 4, &narg
, &bufs
, NULL
, (size_t)0) == -1)
1196 if (kd
->argv
== NULL
) {
1198 * Try to avoid reallocs.
1200 kd
->argc
= MAX(narg
+ 1, 32);
1201 kd
->argv
= _kvm_malloc(kd
, kd
->argc
* sizeof(*kd
->argv
));
1202 if (kd
->argv
== NULL
)
1204 } else if (narg
+ 1 > kd
->argc
) {
1205 kd
->argc
= MAX(2 * kd
->argc
, narg
+ 1);
1206 kd
->argv
= _kvm_realloc(kd
, kd
->argv
, kd
->argc
*
1208 if (kd
->argv
== NULL
)
1212 newargspc_len
= MIN(nchr
, ARG_MAX
);
1213 KVM_ALLOC(kd
, argspc
, newargspc_len
);
1214 memset(kd
->argspc
, 0, (size_t)kd
->argspc_len
); /* XXX necessary? */
1217 mib
[1] = KERN_PROC_ARGS
;
1220 bufs
= kd
->argspc_len
;
1221 if (sysctl(mib
, 4, kd
->argspc
, &bufs
, NULL
, (size_t)0) == -1)
1225 bp
[kd
->argspc_len
-1] = '\0'; /* make sure the string ends with nul */
1227 endp
= bp
+ MIN(nchr
, bufs
);
1232 * XXX: don't need following anymore, or stick check
1233 * for max argc in above while loop?
1235 if (ap
>= kd
->argv
+ kd
->argc
) {
1237 kd
->argv
= _kvm_realloc(kd
, kd
->argv
,
1238 kd
->argc
* sizeof(*kd
->argv
));
1241 bp
+= strlen(bp
) + 1;
1249 kvm_getargv2(kd
, kp
, nchr
)
1251 const struct kinfo_proc2
*kp
;
1255 return (kvm_doargv2(kd
, kp
->p_pid
, KERN_PROC_ARGV
, nchr
));
1259 kvm_getenvv2(kd
, kp
, nchr
)
1261 const struct kinfo_proc2
*kp
;
1265 return (kvm_doargv2(kd
, kp
->p_pid
, KERN_PROC_ENV
, nchr
));
1269 * Read from user space. The user context is given by p.
1272 kvm_ureadm(kd
, p
, uva
, buf
, len
)
1274 const struct miniproc
*p
;
1287 dp
= _kvm_ureadm(kd
, p
, uva
, &cnt
);
1289 _kvm_err(kd
, 0, "invalid address (%lx)", uva
);
1292 cc
= (size_t)MIN(cnt
, len
);
1298 return (ssize_t
)(cp
- buf
);
1302 kvm_uread(kd
, p
, uva
, buf
, len
)
1304 const struct proc
*p
;
1312 return (kvm_ureadm(kd
, &mp
, uva
, buf
, len
));