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