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