1 /* $OpenBSD: kvm_proc.c,v 1.21 2004/01/07 03:47:46 millert Exp $ */ 2 /* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */ 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 /*- 39 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 40 * Copyright (c) 1989, 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software developed by the Computer Systems 44 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 45 * BG 91-66 and contributed to Berkeley. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 */ 71 72 #if defined(LIBC_SCCS) && !defined(lint) 73 #if 0 74 static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93"; 75 #else 76 static char *rcsid = "$OpenBSD: kvm_proc.c,v 1.21 2004/01/07 03:47:46 millert Exp $"; 77 #endif 78 #endif /* LIBC_SCCS and not lint */ 79 80 /* 81 * Proc traversal interface for kvm. ps and w are (probably) the exclusive 82 * users of this code, so we've factored it out into a separate module. 83 * Thus, we keep this grunge out of the other kvm applications (i.e., 84 * most other applications are interested only in open/close/read/nlist). 85 */ 86 87 #include <sys/param.h> 88 #include <sys/user.h> 89 #include <sys/proc.h> 90 #include <sys/exec.h> 91 #include <sys/stat.h> 92 #include <sys/ioctl.h> 93 #include <sys/tty.h> 94 #include <stdlib.h> 95 #include <string.h> 96 #include <unistd.h> 97 #include <nlist.h> 98 #include <kvm.h> 99 100 #include <uvm/uvm_extern.h> 101 #include <uvm/uvm_amap.h> 102 #include <machine/vmparam.h> 103 #include <machine/pmap.h> 104 105 #include <sys/sysctl.h> 106 107 #include <limits.h> 108 #include <db.h> 109 #include <paths.h> 110 111 #include "kvm_private.h" 112 113 /* 114 * Common info from kinfo_proc and kinfo_proc2 used by helper routines. 115 */ 116 struct miniproc { 117 struct vmspace *p_vmspace; 118 char p_stat; 119 struct proc *p_paddr; 120 pid_t p_pid; 121 }; 122 123 /* 124 * Convert from struct proc and kinfo_proc{,2} to miniproc. 125 */ 126 #define PTOMINI(kp, p) \ 127 do { \ 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); 133 134 #define KPTOMINI(kp, p) \ 135 do { \ 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); 141 142 #define KP2TOMINI(kp, p) \ 143 do { \ 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); 149 150 151 #define PTRTOINT64(foo) ((u_int64_t)(u_long)(foo)) 152 153 #define KREAD(kd, addr, obj) \ 154 (kvm_read(kd, addr, (void *)(obj), sizeof(*obj)) != sizeof(*obj)) 155 156 ssize_t kvm_uread(kvm_t *, const struct proc *, u_long, char *, size_t); 157 158 static char *_kvm_ureadm(kvm_t *, const struct miniproc *, u_long, u_long *); 159 static ssize_t kvm_ureadm(kvm_t *, const struct miniproc *, u_long, char *, size_t); 160 161 static char **kvm_argv(kvm_t *, const struct miniproc *, u_long, int, int); 162 163 static int kvm_deadprocs(kvm_t *, int, int, u_long, u_long, int); 164 static char **kvm_doargv(kvm_t *, const struct miniproc *, int, 165 void (*)(struct ps_strings *, u_long *, int *)); 166 static int kvm_proclist(kvm_t *, int, int, struct proc *, 167 struct kinfo_proc *, int); 168 static int proc_verify(kvm_t *, const struct miniproc *); 169 static void ps_str_a(struct ps_strings *, u_long *, int *); 170 static void ps_str_e(struct ps_strings *, u_long *, int *); 171 172 static char * 173 _kvm_ureadm(kd, p, va, cnt) 174 kvm_t *kd; 175 const struct miniproc *p; 176 u_long va; 177 u_long *cnt; 178 { 179 u_long addr, head; 180 u_long offset; 181 struct vm_map_entry vme; 182 struct vm_amap amap; 183 struct vm_anon *anonp, anon; 184 struct vm_page pg; 185 u_long slot; 186 187 if (kd->swapspc == 0) { 188 kd->swapspc = (char *)_kvm_malloc(kd, kd->nbpg); 189 if (kd->swapspc == 0) 190 return (0); 191 } 192 193 /* 194 * Look through the address map for the memory object 195 * that corresponds to the given virtual address. 196 * The header just has the entire valid range. 197 */ 198 head = (u_long)&p->p_vmspace->vm_map.header; 199 addr = head; 200 while (1) { 201 if (KREAD(kd, addr, &vme)) 202 return (0); 203 204 if (va >= vme.start && va < vme.end && 205 vme.aref.ar_amap != NULL) 206 break; 207 208 addr = (u_long)vme.next; 209 if (addr == head) 210 return (0); 211 } 212 213 /* 214 * we found the map entry, now to find the object... 215 */ 216 if (vme.aref.ar_amap == NULL) 217 return NULL; 218 219 addr = (u_long)vme.aref.ar_amap; 220 if (KREAD(kd, addr, &amap)) 221 return NULL; 222 223 offset = va - vme.start; 224 slot = offset / kd->nbpg + vme.aref.ar_pageoff; 225 /* sanity-check slot number */ 226 if (slot > amap.am_nslot) 227 return NULL; 228 229 addr = (u_long)amap.am_anon + (offset / kd->nbpg) * sizeof(anonp); 230 if (KREAD(kd, addr, &anonp)) 231 return NULL; 232 233 addr = (u_long)anonp; 234 if (KREAD(kd, addr, &anon)) 235 return NULL; 236 237 addr = (u_long)anon.u.an_page; 238 if (addr) { 239 if (KREAD(kd, addr, &pg)) 240 return NULL; 241 242 if (_kvm_pread(kd, kd->pmfd, (void *)kd->swapspc, (size_t)kd->nbpg, (off_t)pg.phys_addr) != kd->nbpg) { 243 return NULL; 244 } 245 } else { 246 if (_kvm_pread(kd, kd->swfd, (void *)kd->swapspc, (size_t)kd->nbpg, (off_t)(anon.an_swslot * kd->nbpg)) != kd->nbpg) { 247 return NULL; 248 } 249 } 250 251 /* Found the page. */ 252 offset %= kd->nbpg; 253 *cnt = kd->nbpg - offset; 254 return (&kd->swapspc[offset]); 255 } 256 257 char * 258 _kvm_uread(kd, p, va, cnt) 259 kvm_t *kd; 260 const struct proc *p; 261 u_long va; 262 u_long *cnt; 263 { 264 struct miniproc mp; 265 266 PTOMINI(p, &mp); 267 return (_kvm_ureadm(kd, &mp, va, cnt)); 268 } 269 270 /* 271 * Read proc's from memory file into buffer bp, which has space to hold 272 * at most maxcnt procs. 273 */ 274 static int 275 kvm_proclist(kd, what, arg, p, bp, maxcnt) 276 kvm_t *kd; 277 int what, arg; 278 struct proc *p; 279 struct kinfo_proc *bp; 280 int maxcnt; 281 { 282 int cnt = 0; 283 struct eproc eproc; 284 struct pgrp pgrp; 285 struct session sess; 286 struct tty tty; 287 struct proc proc; 288 289 for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) { 290 if (KREAD(kd, (u_long)p, &proc)) { 291 _kvm_err(kd, kd->program, "can't read proc at %x", p); 292 return (-1); 293 } 294 if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0) 295 KREAD(kd, (u_long)eproc.e_pcred.pc_ucred, 296 &eproc.e_ucred); 297 298 switch(what) { 299 300 case KERN_PROC_PID: 301 if (proc.p_pid != (pid_t)arg) 302 continue; 303 break; 304 305 case KERN_PROC_UID: 306 if (eproc.e_ucred.cr_uid != (uid_t)arg) 307 continue; 308 break; 309 310 case KERN_PROC_RUID: 311 if (eproc.e_pcred.p_ruid != (uid_t)arg) 312 continue; 313 break; 314 315 case KERN_PROC_ALL: 316 if (proc.p_flag & P_SYSTEM) 317 continue; 318 break; 319 } 320 /* 321 * We're going to add another proc to the set. If this 322 * will overflow the buffer, assume the reason is because 323 * nprocs (or the proc list) is corrupt and declare an error. 324 */ 325 if (cnt >= maxcnt) { 326 _kvm_err(kd, kd->program, "nprocs corrupt"); 327 return (-1); 328 } 329 /* 330 * gather eproc 331 */ 332 eproc.e_paddr = p; 333 if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) { 334 _kvm_err(kd, kd->program, "can't read pgrp at %x", 335 proc.p_pgrp); 336 return (-1); 337 } 338 eproc.e_sess = pgrp.pg_session; 339 eproc.e_pgid = pgrp.pg_id; 340 eproc.e_jobc = pgrp.pg_jobc; 341 if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) { 342 _kvm_err(kd, kd->program, "can't read session at %x", 343 pgrp.pg_session); 344 return (-1); 345 } 346 if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) { 347 if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) { 348 _kvm_err(kd, kd->program, 349 "can't read tty at %x", sess.s_ttyp); 350 return (-1); 351 } 352 eproc.e_tdev = tty.t_dev; 353 eproc.e_tsess = tty.t_session; 354 if (tty.t_pgrp != NULL) { 355 if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) { 356 _kvm_err(kd, kd->program, 357 "can't read tpgrp at &x", 358 tty.t_pgrp); 359 return (-1); 360 } 361 eproc.e_tpgid = pgrp.pg_id; 362 } else 363 eproc.e_tpgid = -1; 364 } else 365 eproc.e_tdev = NODEV; 366 eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0; 367 if (sess.s_leader == p) 368 eproc.e_flag |= EPROC_SLEADER; 369 if (proc.p_wmesg) 370 (void)kvm_read(kd, (u_long)proc.p_wmesg, 371 eproc.e_wmesg, WMESGLEN); 372 373 (void)kvm_read(kd, (u_long)proc.p_vmspace, 374 &eproc.e_vm, sizeof(eproc.e_vm)); 375 376 eproc.e_xsize = eproc.e_xrssize = 0; 377 eproc.e_xccount = eproc.e_xswrss = 0; 378 379 switch (what) { 380 381 case KERN_PROC_PGRP: 382 if (eproc.e_pgid != (pid_t)arg) 383 continue; 384 break; 385 386 case KERN_PROC_TTY: 387 if ((proc.p_flag & P_CONTROLT) == 0 || 388 eproc.e_tdev != (dev_t)arg) 389 continue; 390 break; 391 } 392 bcopy(&proc, &bp->kp_proc, sizeof(proc)); 393 bcopy(&eproc, &bp->kp_eproc, sizeof(eproc)); 394 ++bp; 395 ++cnt; 396 } 397 return (cnt); 398 } 399 400 /* 401 * Build proc info array by reading in proc list from a crash dump. 402 * Return number of procs read. maxcnt is the max we will read. 403 */ 404 static int 405 kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt) 406 kvm_t *kd; 407 int what, arg; 408 u_long a_allproc; 409 u_long a_zombproc; 410 int maxcnt; 411 { 412 struct kinfo_proc *bp = kd->procbase; 413 int acnt, zcnt; 414 struct proc *p; 415 416 if (KREAD(kd, a_allproc, &p)) { 417 _kvm_err(kd, kd->program, "cannot read allproc"); 418 return (-1); 419 } 420 acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt); 421 if (acnt < 0) 422 return (acnt); 423 424 if (KREAD(kd, a_zombproc, &p)) { 425 _kvm_err(kd, kd->program, "cannot read zombproc"); 426 return (-1); 427 } 428 zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt); 429 if (zcnt < 0) 430 zcnt = 0; 431 432 return (acnt + zcnt); 433 } 434 435 struct kinfo_proc2 * 436 kvm_getproc2(kd, op, arg, esize, cnt) 437 kvm_t *kd; 438 int op, arg; 439 size_t esize; 440 int *cnt; 441 { 442 size_t size; 443 int mib[6], st, nprocs; 444 struct user user; 445 446 if (esize < 0) 447 return NULL; 448 449 if (kd->procbase2 != NULL) { 450 free(kd->procbase2); 451 /* 452 * Clear this pointer in case this call fails. Otherwise, 453 * kvm_close() will free it again. 454 */ 455 kd->procbase2 = 0; 456 } 457 458 if (ISALIVE(kd)) { 459 size = 0; 460 mib[0] = CTL_KERN; 461 mib[1] = KERN_PROC2; 462 mib[2] = op; 463 mib[3] = arg; 464 mib[4] = esize; 465 mib[5] = 0; 466 st = sysctl(mib, 6, NULL, &size, NULL, 0); 467 if (st == -1) { 468 _kvm_syserr(kd, kd->program, "kvm_getproc2"); 469 return NULL; 470 } 471 472 mib[5] = size / esize; 473 kd->procbase2 = (struct kinfo_proc2 *)_kvm_malloc(kd, size); 474 if (kd->procbase2 == 0) 475 return NULL; 476 st = sysctl(mib, 6, kd->procbase2, &size, NULL, 0); 477 if (st == -1) { 478 _kvm_syserr(kd, kd->program, "kvm_getproc2"); 479 return NULL; 480 } 481 nprocs = size / esize; 482 } else { 483 char *kp2c; 484 struct kinfo_proc *kp; 485 struct kinfo_proc2 kp2, *kp2p; 486 int i; 487 488 kp = kvm_getprocs(kd, op, arg, &nprocs); 489 if (kp == NULL) 490 return NULL; 491 492 kd->procbase2 = _kvm_malloc(kd, nprocs * esize); 493 kp2c = (char *)kd->procbase2; 494 kp2p = &kp2; 495 for (i = 0; i < nprocs; i++, kp++) { 496 memset(kp2p, 0, sizeof(kp2)); 497 kp2p->p_forw = PTRTOINT64(kp->kp_proc.p_forw); 498 kp2p->p_back = PTRTOINT64(kp->kp_proc.p_back); 499 kp2p->p_paddr = PTRTOINT64(kp->kp_eproc.e_paddr); 500 501 kp2p->p_addr = PTRTOINT64(kp->kp_proc.p_addr); 502 kp2p->p_fd = PTRTOINT64(kp->kp_proc.p_fd); 503 kp2p->p_stats = PTRTOINT64(kp->kp_proc.p_stats); 504 kp2p->p_limit = PTRTOINT64(kp->kp_proc.p_limit); 505 kp2p->p_vmspace = PTRTOINT64(kp->kp_proc.p_vmspace); 506 kp2p->p_sigacts = PTRTOINT64(kp->kp_proc.p_sigacts); 507 kp2p->p_sess = PTRTOINT64(kp->kp_eproc.e_sess); 508 kp2p->p_tsess = 0; 509 kp2p->p_ru = PTRTOINT64(kp->kp_proc.p_ru); 510 511 kp2p->p_eflag = 0; 512 kp2p->p_exitsig = kp->kp_proc.p_exitsig; 513 kp2p->p_flag = kp->kp_proc.p_flag; 514 515 kp2p->p_pid = kp->kp_proc.p_pid; 516 517 kp2p->p_ppid = kp->kp_eproc.e_ppid; 518 #if 0 519 kp2p->p_sid = kp->kp_eproc.e_sid; 520 #else 521 kp2p->p_sid = -1; /* XXX */ 522 #endif 523 kp2p->p__pgid = kp->kp_eproc.e_pgid; 524 525 kp2p->p_tpgid = -1; 526 527 kp2p->p_uid = kp->kp_eproc.e_ucred.cr_uid; 528 kp2p->p_ruid = kp->kp_eproc.e_pcred.p_ruid; 529 kp2p->p_gid = kp->kp_eproc.e_ucred.cr_gid; 530 kp2p->p_rgid = kp->kp_eproc.e_pcred.p_rgid; 531 532 memcpy(kp2p->p_groups, kp->kp_eproc.e_ucred.cr_groups, 533 MIN(sizeof(kp2p->p_groups), sizeof(kp->kp_eproc.e_ucred.cr_groups))); 534 kp2p->p_ngroups = kp->kp_eproc.e_ucred.cr_ngroups; 535 536 kp2p->p_jobc = kp->kp_eproc.e_jobc; 537 kp2p->p_tdev = kp->kp_eproc.e_tdev; 538 kp2p->p_tpgid = kp->kp_eproc.e_tpgid; 539 kp2p->p_tsess = PTRTOINT64(kp->kp_eproc.e_tsess); 540 541 kp2p->p_estcpu = kp->kp_proc.p_estcpu; 542 kp2p->p_rtime_sec = kp->kp_proc.p_estcpu; 543 kp2p->p_rtime_usec = kp->kp_proc.p_estcpu; 544 kp2p->p_cpticks = kp->kp_proc.p_cpticks; 545 kp2p->p_pctcpu = kp->kp_proc.p_pctcpu; 546 kp2p->p_swtime = kp->kp_proc.p_swtime; 547 kp2p->p_slptime = kp->kp_proc.p_slptime; 548 kp2p->p_schedflags = kp->kp_proc.p_schedflags; 549 550 kp2p->p_uticks = kp->kp_proc.p_uticks; 551 kp2p->p_sticks = kp->kp_proc.p_sticks; 552 kp2p->p_iticks = kp->kp_proc.p_iticks; 553 554 kp2p->p_tracep = PTRTOINT64(kp->kp_proc.p_tracep); 555 kp2p->p_traceflag = kp->kp_proc.p_traceflag; 556 557 kp2p->p_holdcnt = kp->kp_proc.p_holdcnt; 558 559 kp2p->p_siglist = kp->kp_proc.p_siglist; 560 kp2p->p_sigmask = kp->kp_proc.p_sigmask; 561 kp2p->p_sigignore = kp->kp_proc.p_sigignore; 562 kp2p->p_sigcatch = kp->kp_proc.p_sigcatch; 563 564 kp2p->p_stat = kp->kp_proc.p_stat; 565 kp2p->p_priority = kp->kp_proc.p_priority; 566 kp2p->p_usrpri = kp->kp_proc.p_usrpri; 567 kp2p->p_nice = kp->kp_proc.p_nice; 568 569 kp2p->p_xstat = kp->kp_proc.p_xstat; 570 kp2p->p_acflag = kp->kp_proc.p_acflag; 571 572 strncpy(kp2p->p_comm, kp->kp_proc.p_comm, 573 MIN(sizeof(kp2p->p_comm), sizeof(kp->kp_proc.p_comm))); 574 575 strncpy(kp2p->p_wmesg, kp->kp_eproc.e_wmesg, sizeof(kp2p->p_wmesg)); 576 kp2p->p_wchan = PTRTOINT64(kp->kp_proc.p_wchan); 577 578 strncpy(kp2p->p_login, kp->kp_eproc.e_login, sizeof(kp2p->p_login)); 579 580 kp2p->p_vm_rssize = kp->kp_eproc.e_xrssize; 581 kp2p->p_vm_tsize = kp->kp_eproc.e_vm.vm_tsize; 582 kp2p->p_vm_dsize = kp->kp_eproc.e_vm.vm_dsize; 583 kp2p->p_vm_ssize = kp->kp_eproc.e_vm.vm_ssize; 584 585 kp2p->p_eflag = kp->kp_eproc.e_flag; 586 587 if (P_ZOMBIE(&kp->kp_proc) || kp->kp_proc.p_addr == NULL || 588 KREAD(kd, (u_long)kp->kp_proc.p_addr, &user)) { 589 kp2p->p_uvalid = 0; 590 } else { 591 kp2p->p_uvalid = 1; 592 593 kp2p->p_ustart_sec = user.u_stats.p_start.tv_sec; 594 kp2p->p_ustart_usec = user.u_stats.p_start.tv_usec; 595 596 kp2p->p_uutime_sec = user.u_stats.p_ru.ru_utime.tv_sec; 597 kp2p->p_uutime_usec = user.u_stats.p_ru.ru_utime.tv_usec; 598 kp2p->p_ustime_sec = user.u_stats.p_ru.ru_stime.tv_sec; 599 kp2p->p_ustime_usec = user.u_stats.p_ru.ru_stime.tv_usec; 600 601 kp2p->p_uru_maxrss = user.u_stats.p_ru.ru_maxrss; 602 kp2p->p_uru_ixrss = user.u_stats.p_ru.ru_ixrss; 603 kp2p->p_uru_idrss = user.u_stats.p_ru.ru_idrss; 604 kp2p->p_uru_isrss = user.u_stats.p_ru.ru_isrss; 605 kp2p->p_uru_minflt = user.u_stats.p_ru.ru_minflt; 606 kp2p->p_uru_majflt = user.u_stats.p_ru.ru_majflt; 607 kp2p->p_uru_nswap = user.u_stats.p_ru.ru_nswap; 608 kp2p->p_uru_inblock = user.u_stats.p_ru.ru_inblock; 609 kp2p->p_uru_oublock = user.u_stats.p_ru.ru_oublock; 610 kp2p->p_uru_msgsnd = user.u_stats.p_ru.ru_msgsnd; 611 kp2p->p_uru_msgrcv = user.u_stats.p_ru.ru_msgrcv; 612 kp2p->p_uru_nsignals = user.u_stats.p_ru.ru_nsignals; 613 kp2p->p_uru_nvcsw = user.u_stats.p_ru.ru_nvcsw; 614 kp2p->p_uru_nivcsw = user.u_stats.p_ru.ru_nivcsw; 615 616 kp2p->p_uctime_sec = user.u_stats.p_cru.ru_utime.tv_sec + 617 user.u_stats.p_cru.ru_stime.tv_sec; 618 kp2p->p_uctime_usec = user.u_stats.p_cru.ru_utime.tv_usec + 619 user.u_stats.p_cru.ru_stime.tv_usec; 620 } 621 622 memcpy(kp2c, &kp2, esize); 623 kp2c += esize; 624 } 625 626 free(kd->procbase); 627 } 628 *cnt = nprocs; 629 return (kd->procbase2); 630 } 631 632 struct kinfo_proc * 633 kvm_getprocs(kd, op, arg, cnt) 634 kvm_t *kd; 635 int op, arg; 636 int *cnt; 637 { 638 size_t size; 639 int mib[4], st, nprocs; 640 641 if (kd->procbase != 0) { 642 free((void *)kd->procbase); 643 /* 644 * Clear this pointer in case this call fails. Otherwise, 645 * kvm_close() will free it again. 646 */ 647 kd->procbase = 0; 648 } 649 if (ISALIVE(kd)) { 650 size = 0; 651 mib[0] = CTL_KERN; 652 mib[1] = KERN_PROC; 653 mib[2] = op; 654 mib[3] = arg; 655 st = sysctl(mib, 4, NULL, &size, NULL, 0); 656 if (st == -1) { 657 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 658 return (0); 659 } 660 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 661 if (kd->procbase == 0) 662 return (0); 663 st = sysctl(mib, 4, kd->procbase, &size, NULL, 0); 664 if (st == -1) { 665 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 666 return (0); 667 } 668 if (size % sizeof(struct kinfo_proc) != 0) { 669 _kvm_err(kd, kd->program, 670 "proc size mismatch (%d total, %d chunks)", 671 size, sizeof(struct kinfo_proc)); 672 return (0); 673 } 674 nprocs = size / sizeof(struct kinfo_proc); 675 } else { 676 struct nlist nl[4], *p; 677 678 memset(nl, 0, sizeof(nl)); 679 nl[0].n_name = "_nprocs"; 680 nl[1].n_name = "_allproc"; 681 nl[2].n_name = "_zombproc"; 682 nl[3].n_name = NULL; 683 684 if (kvm_nlist(kd, nl) != 0) { 685 for (p = nl; p->n_type != 0; ++p) 686 ; 687 _kvm_err(kd, kd->program, 688 "%s: no such symbol", p->n_name); 689 return (0); 690 } 691 if (KREAD(kd, nl[0].n_value, &nprocs)) { 692 _kvm_err(kd, kd->program, "can't read nprocs"); 693 return (0); 694 } 695 size = nprocs * sizeof(struct kinfo_proc); 696 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 697 if (kd->procbase == 0) 698 return (0); 699 700 nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, 701 nl[2].n_value, nprocs); 702 #ifdef notdef 703 size = nprocs * sizeof(struct kinfo_proc); 704 (void)realloc(kd->procbase, size); 705 #endif 706 } 707 *cnt = nprocs; 708 return (kd->procbase); 709 } 710 711 void 712 _kvm_freeprocs(kd) 713 kvm_t *kd; 714 { 715 if (kd->procbase) { 716 free(kd->procbase); 717 kd->procbase = 0; 718 } 719 } 720 721 void * 722 _kvm_realloc(kd, p, n) 723 kvm_t *kd; 724 void *p; 725 size_t n; 726 { 727 void *np = (void *)realloc(p, n); 728 729 if (np == 0) 730 _kvm_err(kd, kd->program, "out of memory"); 731 return (np); 732 } 733 734 /* 735 * Read in an argument vector from the user address space of process p. 736 * addr if the user-space base address of narg null-terminated contiguous 737 * strings. This is used to read in both the command arguments and 738 * environment strings. Read at most maxcnt characters of strings. 739 */ 740 static char ** 741 kvm_argv(kd, p, addr, narg, maxcnt) 742 kvm_t *kd; 743 const struct miniproc *p; 744 u_long addr; 745 int narg; 746 int maxcnt; 747 { 748 char *np, *cp, *ep, *ap; 749 u_long oaddr = -1; 750 int len, cc; 751 char **argv; 752 753 /* 754 * Check that there aren't an unreasonable number of agruments, 755 * and that the address is in user space. 756 */ 757 if (narg > ARG_MAX || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS) 758 return (0); 759 760 if (kd->argv == 0) { 761 /* 762 * Try to avoid reallocs. 763 */ 764 kd->argc = MAX(narg + 1, 32); 765 kd->argv = (char **)_kvm_malloc(kd, kd->argc * 766 sizeof(*kd->argv)); 767 if (kd->argv == 0) 768 return (0); 769 } else if (narg + 1 > kd->argc) { 770 kd->argc = MAX(2 * kd->argc, narg + 1); 771 kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * 772 sizeof(*kd->argv)); 773 if (kd->argv == 0) 774 return (0); 775 } 776 if (kd->argspc == 0) { 777 kd->argspc = (char *)_kvm_malloc(kd, kd->nbpg); 778 if (kd->argspc == 0) 779 return (0); 780 kd->arglen = kd->nbpg; 781 } 782 if (kd->argbuf == 0) { 783 kd->argbuf = (char *)_kvm_malloc(kd, kd->nbpg); 784 if (kd->argbuf == 0) 785 return (0); 786 } 787 cc = sizeof(char *) * narg; 788 if (kvm_ureadm(kd, p, addr, (char *)kd->argv, cc) != cc) 789 return (0); 790 ap = np = kd->argspc; 791 argv = kd->argv; 792 len = 0; 793 /* 794 * Loop over pages, filling in the argument vector. 795 */ 796 while (argv < kd->argv + narg && *argv != 0) { 797 addr = (u_long)*argv & ~(kd->nbpg - 1); 798 if (addr != oaddr) { 799 if (kvm_ureadm(kd, p, addr, kd->argbuf, kd->nbpg) != 800 kd->nbpg) 801 return (0); 802 oaddr = addr; 803 } 804 addr = (u_long)*argv & (kd->nbpg - 1); 805 cp = kd->argbuf + addr; 806 cc = kd->nbpg - addr; 807 if (maxcnt > 0 && cc > maxcnt - len) 808 cc = maxcnt - len; 809 ep = memchr(cp, '\0', cc); 810 if (ep != 0) 811 cc = ep - cp + 1; 812 if (len + cc > kd->arglen) { 813 int off; 814 char **pp; 815 char *op = kd->argspc; 816 817 kd->arglen *= 2; 818 kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, 819 kd->arglen); 820 if (kd->argspc == 0) 821 return (0); 822 /* 823 * Adjust argv pointers in case realloc moved 824 * the string space. 825 */ 826 off = kd->argspc - op; 827 for (pp = kd->argv; pp < argv; pp++) 828 *pp += off; 829 ap += off; 830 np += off; 831 } 832 memcpy(np, cp, cc); 833 np += cc; 834 len += cc; 835 if (ep != 0) { 836 *argv++ = ap; 837 ap = np; 838 } else 839 *argv += cc; 840 if (maxcnt > 0 && len >= maxcnt) { 841 /* 842 * We're stopping prematurely. Terminate the 843 * current string. 844 */ 845 if (ep == 0) { 846 *np = '\0'; 847 *argv++ = ap; 848 } 849 break; 850 } 851 } 852 /* Make sure argv is terminated. */ 853 *argv = 0; 854 return (kd->argv); 855 } 856 857 static void 858 ps_str_a(p, addr, n) 859 struct ps_strings *p; 860 u_long *addr; 861 int *n; 862 { 863 *addr = (u_long)p->ps_argvstr; 864 *n = p->ps_nargvstr; 865 } 866 867 static void 868 ps_str_e(p, addr, n) 869 struct ps_strings *p; 870 u_long *addr; 871 int *n; 872 { 873 *addr = (u_long)p->ps_envstr; 874 *n = p->ps_nenvstr; 875 } 876 877 /* 878 * Determine if the proc indicated by p is still active. 879 * This test is not 100% foolproof in theory, but chances of 880 * being wrong are very low. 881 */ 882 static int 883 proc_verify(kd, p) 884 kvm_t *kd; 885 const struct miniproc *p; 886 { 887 struct proc kernproc; 888 889 /* 890 * Just read in the whole proc. It's not that big relative 891 * to the cost of the read system call. 892 */ 893 if (kvm_read(kd, (u_long)p->p_paddr, &kernproc, sizeof(kernproc)) != 894 sizeof(kernproc)) 895 return (0); 896 return (p->p_pid == kernproc.p_pid && 897 (kernproc.p_stat != SZOMB || p->p_stat == SZOMB)); 898 } 899 900 static char ** 901 kvm_doargv(kd, p, nchr, info) 902 kvm_t *kd; 903 const struct miniproc *p; 904 int nchr; 905 void (*info)(struct ps_strings *, u_long *, int *); 906 { 907 char **ap; 908 u_long addr; 909 int cnt; 910 struct ps_strings arginfo; 911 static struct ps_strings *ps; 912 913 if (ps == NULL) { 914 struct _ps_strings _ps; 915 int mib[2]; 916 size_t len; 917 918 mib[0] = CTL_VM; 919 mib[1] = VM_PSSTRINGS; 920 len = sizeof(_ps); 921 sysctl(mib, 2, &_ps, &len, NULL, 0); 922 ps = (struct ps_strings *)_ps.val; 923 } 924 925 /* 926 * Pointers are stored at the top of the user stack. 927 */ 928 if (p->p_stat == SZOMB || 929 kvm_ureadm(kd, p, (u_long)ps, (char *)&arginfo, 930 sizeof(arginfo)) != sizeof(arginfo)) 931 return (0); 932 933 (*info)(&arginfo, &addr, &cnt); 934 if (cnt == 0) 935 return (0); 936 ap = kvm_argv(kd, p, addr, cnt, nchr); 937 /* 938 * For live kernels, make sure this process didn't go away. 939 */ 940 if (ap != 0 && ISALIVE(kd) && !proc_verify(kd, p)) 941 ap = 0; 942 return (ap); 943 } 944 945 static char ** 946 kvm_arg_sysctl(kvm_t *kd, pid_t pid, int nchr, int env) 947 { 948 int mib[4]; 949 size_t len, orglen; 950 int ret; 951 char *buf; 952 953 orglen = kd->nbpg; 954 if (kd->argbuf == NULL && 955 (kd->argbuf = _kvm_malloc(kd, orglen)) == NULL) 956 return (NULL); 957 958 again: 959 mib[0] = CTL_KERN; 960 mib[1] = KERN_PROC_ARGS; 961 mib[2] = (int)pid; 962 mib[3] = env ? KERN_PROC_ENV : KERN_PROC_ARGV; 963 964 len = orglen; 965 ret = (sysctl(mib, 4, kd->argbuf, &len, NULL, 0) < 0); 966 if (ret && errno == ENOMEM) { 967 orglen += kd->nbpg; 968 buf = _kvm_realloc(kd, kd->argbuf, orglen); 969 if (buf == NULL) 970 return (NULL); 971 kd->argbuf = buf; 972 goto again; 973 } 974 975 if (ret) { 976 free(kd->argbuf); 977 kd->argbuf = NULL; 978 _kvm_syserr(kd, kd->program, "kvm_arg_sysctl"); 979 return (NULL); 980 } 981 #if 0 982 for (argv = (char **)kd->argbuf; *argv != NULL; argv++) 983 if (strlen(*argv) > nchr) 984 *argv[nchr] = '\0'; 985 #endif 986 987 return (char **)(kd->argbuf); 988 } 989 990 /* 991 * Get the command args. This code is now machine independent. 992 */ 993 char ** 994 kvm_getargv(kd, kp, nchr) 995 kvm_t *kd; 996 const struct kinfo_proc *kp; 997 int nchr; 998 { 999 struct miniproc p; 1000 1001 if (ISALIVE(kd)) 1002 return (kvm_arg_sysctl(kd, kp->kp_proc.p_pid, nchr, 0)); 1003 KPTOMINI(kp, &p); 1004 return (kvm_doargv(kd, &p, nchr, ps_str_a)); 1005 } 1006 1007 char ** 1008 kvm_getenvv(kd, kp, nchr) 1009 kvm_t *kd; 1010 const struct kinfo_proc *kp; 1011 int nchr; 1012 { 1013 struct miniproc p; 1014 1015 if (ISALIVE(kd)) 1016 return (kvm_arg_sysctl(kd, kp->kp_proc.p_pid, nchr, 1)); 1017 KPTOMINI(kp, &p); 1018 return (kvm_doargv(kd, &p, nchr, ps_str_e)); 1019 } 1020 1021 char ** 1022 kvm_getargv2(kd, kp, nchr) 1023 kvm_t *kd; 1024 const struct kinfo_proc2 *kp; 1025 int nchr; 1026 { 1027 struct miniproc p; 1028 1029 if (ISALIVE(kd)) 1030 return (kvm_arg_sysctl(kd, kp->p_pid, nchr, 0)); 1031 KP2TOMINI(kp, &p); 1032 return (kvm_doargv(kd, &p, nchr, ps_str_a)); 1033 } 1034 1035 char ** 1036 kvm_getenvv2(kd, kp, nchr) 1037 kvm_t *kd; 1038 const struct kinfo_proc2 *kp; 1039 int nchr; 1040 { 1041 struct miniproc p; 1042 1043 if (ISALIVE(kd)) 1044 return (kvm_arg_sysctl(kd, kp->p_pid, nchr, 1)); 1045 KP2TOMINI(kp, &p); 1046 return (kvm_doargv(kd, &p, nchr, ps_str_e)); 1047 } 1048 1049 /* 1050 * Read from user space. The user context is given by p. 1051 */ 1052 static ssize_t 1053 kvm_ureadm(kd, p, uva, buf, len) 1054 kvm_t *kd; 1055 const struct miniproc *p; 1056 u_long uva; 1057 char *buf; 1058 size_t len; 1059 { 1060 char *cp; 1061 1062 cp = buf; 1063 while (len > 0) { 1064 size_t cc; 1065 char *dp; 1066 u_long cnt; 1067 1068 dp = _kvm_ureadm(kd, p, uva, &cnt); 1069 if (dp == 0) { 1070 _kvm_err(kd, 0, "invalid address (%lx)", uva); 1071 return (0); 1072 } 1073 cc = (size_t)MIN(cnt, len); 1074 bcopy(dp, cp, cc); 1075 cp += cc; 1076 uva += cc; 1077 len -= cc; 1078 } 1079 return (ssize_t)(cp - buf); 1080 } 1081 1082 ssize_t 1083 kvm_uread(kd, p, uva, buf, len) 1084 kvm_t *kd; 1085 const struct proc *p; 1086 u_long uva; 1087 char *buf; 1088 size_t len; 1089 { 1090 struct miniproc mp; 1091 1092 PTOMINI(p, &mp); 1093 return (kvm_ureadm(kd, &mp, uva, buf, len)); 1094 } 1095