1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * This file contains a set of generic routines for periodically 29 * sampling the state of another process, or tree of processes. 30 * 31 * It is built upon the infrastructure provided by libproc. 32 */ 33 34 #include <sys/wait.h> 35 #include <sys/syscall.h> 36 #include <sys/time.h> 37 #include <libproc.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <errno.h> 41 #include <unistd.h> 42 #include <signal.h> 43 #include <string.h> 44 #include <strings.h> 45 #include <limits.h> 46 #include <ctype.h> 47 #include <libintl.h> 48 #include <libcpc.h> 49 #include <sys/cpc_impl.h> 50 51 #include "libpctx.h" 52 53 struct __pctx { 54 pctx_errfn_t *errfn; 55 struct ps_prochandle *Pr; 56 void *uarg; 57 pctx_sysc_execfn_t *exec; 58 pctx_sysc_forkfn_t *fork; 59 pctx_sysc_exitfn_t *exit; 60 pctx_sysc_lwp_createfn_t *lwp_create; 61 pctx_init_lwpfn_t *init_lwp; 62 pctx_fini_lwpfn_t *fini_lwp; 63 pctx_sysc_lwp_exitfn_t *lwp_exit; 64 int verbose; 65 int created; 66 int sigblocked; 67 int terminate; 68 sigset_t savedset; 69 cpc_t *cpc; 70 }; 71 72 static void (*pctx_cpc_callback)(cpc_t *cpc, struct __pctx *pctx); 73 74 static void 75 pctx_default_errfn(const char *fn, const char *fmt, va_list ap) 76 { 77 (void) fprintf(stderr, "libpctx: pctx_%s: ", fn); 78 (void) vfprintf(stderr, fmt, ap); 79 } 80 81 /*PRINTFLIKE3*/ 82 static void 83 pctx_error(pctx_t *pctx, const char *fn, const char *fmt, ...) 84 { 85 va_list ap; 86 87 va_start(ap, fmt); 88 pctx->errfn(fn, fmt, ap); 89 va_end(ap); 90 } 91 92 /* 93 * Create a new process and bind the user args for it 94 */ 95 pctx_t * 96 pctx_create( 97 const char *filename, 98 char *const *argv, 99 void *arg, 100 int verbose, 101 pctx_errfn_t *errfn) 102 { 103 static const char fn[] = "create"; 104 int err; 105 pctx_t *pctx; 106 107 pctx = calloc(1, sizeof (*pctx)); 108 pctx->uarg = arg; 109 pctx->verbose = verbose; 110 pctx->terminate = 0; 111 pctx->errfn = errfn ? errfn : pctx_default_errfn; 112 113 if ((pctx->Pr = Pcreate(filename, argv, &err, 0, 0)) == NULL) { 114 switch (err) { 115 case C_PERM: 116 pctx_error(pctx, fn, gettext("cannot trace set-id or " 117 "unreadable program '%s'\n"), filename); 118 break; 119 case C_LP64: 120 pctx_error(pctx, fn, gettext("cannot control LP64 " 121 "program '%s'\n"), filename); 122 break; 123 case C_NOEXEC: 124 pctx_error(pctx, fn, gettext("cannot execute " 125 "program '%s'\n"), filename); 126 break; 127 case C_NOENT: 128 pctx_error(pctx, fn, gettext("cannot find" 129 "program '%s'\n"), filename); 130 break; 131 case C_FORK: 132 pctx_error(pctx, fn, gettext("cannot fork, " 133 "program '%s'\n"), filename); 134 break; 135 default: 136 pctx_error(pctx, fn, gettext("%s, program '%s'\n"), 137 Pcreate_error(err), filename); 138 break; 139 } 140 free(pctx); 141 return (NULL); 142 } 143 144 if (Psysentry(pctx->Pr, SYS_exit, 1) == -1) { 145 pctx_error(pctx, fn, 146 gettext("can't stop-on-exit() program '%s'\n"), filename); 147 Prelease(pctx->Pr, PRELEASE_KILL); 148 free(pctx); 149 return (NULL); 150 } 151 /* 152 * Set kill-on-last-close so the controlled process 153 * dies if we die. 154 */ 155 pctx->created = 1; 156 (void) Psetflags(pctx->Pr, PR_KLC); 157 (void) pctx_set_events(pctx, PCTX_NULL_EVENT); 158 159 return (pctx); 160 } 161 162 /* 163 * Capture an existing process and bind the user args for it 164 */ 165 pctx_t * 166 pctx_capture(pid_t pid, void *arg, int verbose, pctx_errfn_t *errfn) 167 { 168 static const char fn[] = "capture"; 169 int err; 170 pctx_t *pctx; 171 172 pctx = calloc(1, sizeof (*pctx)); 173 pctx->uarg = arg; 174 pctx->verbose = verbose; 175 pctx->errfn = errfn ? errfn : pctx_default_errfn; 176 177 if ((pctx->Pr = Pgrab(pid, 0, &err)) == NULL) { 178 switch (err) { 179 case G_NOPROC: 180 pctx_error(pctx, fn, 181 gettext("pid %d doesn't exist\n"), (int)pid); 182 break; 183 case G_ZOMB: 184 pctx_error(pctx, fn, 185 gettext("pid %d is a zombie\n"), (int)pid); 186 break; 187 case G_PERM: 188 pctx_error(pctx, fn, 189 gettext("pid %d: permission denied\n"), (int)pid); 190 break; 191 case G_BUSY: 192 pctx_error(pctx, fn, 193 gettext("pid %d is already being traced\n"), 194 (int)pid); 195 break; 196 case G_SYS: 197 pctx_error(pctx, fn, 198 gettext("pid %d is a system process\n"), (int)pid); 199 break; 200 case G_SELF: 201 pctx_error(pctx, fn, 202 gettext("cannot capture self!\n")); 203 break; 204 case G_LP64: 205 pctx_error(pctx, fn, gettext("cannot control LP64 " 206 "process, pid %d\n"), (int)pid); 207 break; 208 default: 209 pctx_error(pctx, fn, gettext("%s: pid %d\n"), 210 Pgrab_error(err), (int)pid); 211 break; 212 } 213 free(pctx); 214 return (NULL); 215 } 216 217 if (Psysentry(pctx->Pr, SYS_exit, 1) == -1) { 218 pctx_error(pctx, fn, 219 gettext("can't stop-on-exit() pid %d\n"), (int)pid); 220 Prelease(pctx->Pr, PRELEASE_CLEAR); 221 free(pctx); 222 return (NULL); 223 } 224 225 /* 226 * Set run-on-last-close so the controlled process 227 * runs even if we die on a signal. This is because 228 * we grabbed an existing process - it would be impolite 229 * to cause it to die if we exit prematurely. 230 */ 231 pctx->created = 0; 232 (void) Psetflags(pctx->Pr, PR_RLC); 233 (void) pctx_set_events(pctx, PCTX_NULL_EVENT); 234 235 return (pctx); 236 } 237 238 /*ARGSUSED*/ 239 static void 240 default_void(pctx_t *pctx) 241 {} 242 243 /*ARGSUSED*/ 244 static int 245 default_int(pctx_t *pctx) 246 { 247 return (0); 248 } 249 250 int 251 pctx_set_events(pctx_t *pctx, ...) 252 { 253 static const char fn[] = "set_events"; 254 va_list pvar; 255 int error = 0; 256 pctx_event_t event; 257 258 va_start(pvar, pctx); 259 do { 260 switch (event = (pctx_event_t)va_arg(pvar, pctx_event_t)) { 261 case PCTX_NULL_EVENT: 262 break; 263 case PCTX_SYSC_EXEC_EVENT: 264 pctx->exec = (pctx_sysc_execfn_t *) 265 va_arg(pvar, pctx_sysc_execfn_t *); 266 break; 267 case PCTX_SYSC_FORK_EVENT: 268 pctx->fork = (pctx_sysc_forkfn_t *) 269 va_arg(pvar, pctx_sysc_forkfn_t *); 270 break; 271 case PCTX_SYSC_EXIT_EVENT: /* always intercepted */ 272 pctx->exit = (pctx_sysc_exitfn_t *) 273 va_arg(pvar, pctx_sysc_exitfn_t *); 274 break; 275 case PCTX_SYSC_LWP_CREATE_EVENT: 276 pctx->lwp_create = (pctx_sysc_lwp_createfn_t *) 277 va_arg(pvar, pctx_sysc_lwp_createfn_t *); 278 break; 279 case PCTX_INIT_LWP_EVENT: 280 pctx->init_lwp = (pctx_init_lwpfn_t *) 281 va_arg(pvar, pctx_init_lwpfn_t *); 282 break; 283 case PCTX_FINI_LWP_EVENT: 284 pctx->fini_lwp = (pctx_fini_lwpfn_t *) 285 va_arg(pvar, pctx_fini_lwpfn_t *); 286 break; 287 case PCTX_SYSC_LWP_EXIT_EVENT: 288 pctx->lwp_exit = (pctx_sysc_lwp_exitfn_t *) 289 va_arg(pvar, pctx_sysc_lwp_exitfn_t *); 290 break; 291 default: 292 pctx_error(pctx, fn, 293 gettext("unknown event type %x\n"), event); 294 error = -1; 295 break; 296 } 297 } while (event != PCTX_NULL_EVENT && error == 0); 298 va_end(pvar); 299 300 if (error != 0) 301 return (error); 302 303 if (pctx->exec == NULL) 304 pctx->exec = (pctx_sysc_execfn_t *)(uintptr_t)default_int; 305 if (pctx->fork == NULL) 306 pctx->fork = (pctx_sysc_forkfn_t *)(uintptr_t)default_void; 307 if (pctx->exit == NULL) 308 pctx->exit = (pctx_sysc_exitfn_t *)(uintptr_t)default_void; 309 if (pctx->lwp_create == NULL) 310 pctx->lwp_create = (pctx_sysc_lwp_createfn_t *) 311 (uintptr_t)default_int; 312 if (pctx->init_lwp == NULL) 313 pctx->init_lwp = (pctx_init_lwpfn_t *)(uintptr_t)default_int; 314 if (pctx->fini_lwp == NULL) 315 pctx->fini_lwp = (pctx_fini_lwpfn_t *)(uintptr_t)default_int; 316 if (pctx->lwp_exit == NULL) 317 pctx->lwp_exit = (pctx_sysc_lwp_exitfn_t *) 318 (uintptr_t)default_int; 319 320 if ((uintptr_t)pctx->fork != (uintptr_t)default_void) { 321 (void) Psysexit(pctx->Pr, SYS_vfork, 1); 322 (void) Psysexit(pctx->Pr, SYS_forksys, 1); 323 if (Psetflags(pctx->Pr, PR_FORK) == -1) 324 error = -1; 325 } else { 326 (void) Psysexit(pctx->Pr, SYS_vfork, 0); 327 (void) Psysexit(pctx->Pr, SYS_forksys, 0); 328 if (Punsetflags(pctx->Pr, PR_FORK) == -1) 329 error = -1; 330 } 331 332 /* 333 * exec causes termination of all but the exec-ing lwp, 334 * and resets the lwpid to one in the new address space. 335 */ 336 if ((uintptr_t)pctx->exec != (uintptr_t)default_int || 337 (uintptr_t)pctx->fini_lwp != (uintptr_t)default_int || 338 (uintptr_t)pctx->init_lwp != (uintptr_t)default_int) { 339 (void) Psysexit(pctx->Pr, SYS_execve, 1); 340 (void) Psysentry(pctx->Pr, SYS_execve, 1); 341 } else { 342 (void) Psysexit(pctx->Pr, SYS_execve, 0); 343 (void) Psysentry(pctx->Pr, SYS_execve, 0); 344 } 345 346 (void) Psysexit(pctx->Pr, SYS_lwp_create, 347 (uintptr_t)pctx->lwp_create != (uintptr_t)default_int || 348 (uintptr_t)pctx->init_lwp != (uintptr_t)default_int); 349 350 (void) Psysentry(pctx->Pr, SYS_lwp_exit, 351 (uintptr_t)pctx->lwp_exit != (uintptr_t)default_int || 352 (uintptr_t)pctx->fini_lwp != (uintptr_t)default_int); 353 354 return (0); 355 } 356 357 static sigset_t termsig; 358 359 static void 360 __libpctx_init(void) 361 { 362 /* 363 * Initialize the signal set used to shield ourselves from 364 * death-by-terminal-signal while the agent lwp is running. 365 */ 366 (void) sigemptyset(&termsig); 367 (void) sigaddset(&termsig, SIGHUP); 368 (void) sigaddset(&termsig, SIGTERM); 369 (void) sigaddset(&termsig, SIGINT); 370 (void) sigaddset(&termsig, SIGQUIT); 371 } 372 373 #pragma init(__libpctx_init) 374 375 static void 376 pctx_begin_syscalls(pctx_t *pctx) 377 { 378 if (pctx->Pr == NULL) 379 return; 380 if (pctx->sigblocked++ == 0) { 381 (void) sigprocmask(SIG_BLOCK, &termsig, &pctx->savedset); 382 (void) Pcreate_agent(pctx->Pr); 383 } 384 } 385 386 static void 387 pctx_end_syscalls(pctx_t *pctx) 388 { 389 if (pctx->Pr == NULL) 390 return; 391 if (--pctx->sigblocked == 0) { 392 (void) Pdestroy_agent(pctx->Pr); 393 (void) sigprocmask(SIG_SETMASK, &pctx->savedset, NULL); 394 } 395 } 396 397 /* 398 * Iterate over the valid lwpids in the process, invoking the 399 * action function on each one. 400 */ 401 static int 402 pctx_lwpiterate(pctx_t *pctx, int (*action)(pctx_t *, pid_t, id_t, void *)) 403 { 404 const pstatus_t *pstatus; 405 char lstatus[64]; 406 struct stat statb; 407 lwpstatus_t *lwps; 408 prheader_t *prh; 409 int fd, nlwp; 410 int ret = 0; 411 412 if ((uintptr_t)action == (uintptr_t)default_int) 413 return (0); 414 415 pstatus = Pstatus(pctx->Pr); 416 if (pstatus->pr_nlwp <= 1) { 417 pctx_begin_syscalls(pctx); 418 ret = action(pctx, pstatus->pr_pid, 1, pctx->uarg); 419 pctx_end_syscalls(pctx); 420 return (ret); 421 } 422 423 (void) snprintf(lstatus, sizeof (lstatus), 424 "/proc/%d/lstatus", (int)pstatus->pr_pid); 425 426 if ((fd = open(lstatus, O_RDONLY)) < 0 || 427 fstat(fd, &statb) != 0) { 428 if (fd >= 0) 429 (void) close(fd); 430 return (-1); 431 } 432 433 prh = malloc(statb.st_size); 434 if (read(fd, prh, statb.st_size) < 435 sizeof (prheader_t) + sizeof (lwpstatus_t)) { 436 (void) close(fd); 437 free(prh); 438 return (-1); 439 } 440 (void) close(fd); 441 442 /* LINTED pointer cast may result in improper alignment */ 443 lwps = (lwpstatus_t *)(prh + 1); 444 pctx_begin_syscalls(pctx); 445 for (nlwp = prh->pr_nent; nlwp > 0; nlwp--) { 446 if (action(pctx, 447 pstatus->pr_pid, lwps->pr_lwpid, pctx->uarg) != 0) 448 ret = -1; 449 /* LINTED pointer cast may result in improper alignment */ 450 lwps = (lwpstatus_t *)((char *)lwps + prh->pr_entsize); 451 } 452 pctx_end_syscalls(pctx); 453 free(prh); 454 return (ret); 455 } 456 457 /* 458 * Free any associated state, but leave the process stopped if it 459 * is still under our control. (If it isn't under our control, 460 * it should just run to completion when we do our last close) 461 */ 462 static void 463 pctx_free(pctx_t *pctx) 464 { 465 if (pctx->cpc != NULL && pctx_cpc_callback != NULL) 466 (*pctx_cpc_callback)(pctx->cpc, pctx); 467 if (pctx->Pr) { 468 Pfree(pctx->Pr); 469 pctx->Pr = NULL; 470 } 471 pctx->errfn = pctx_default_errfn; 472 } 473 474 /* 475 * Completely release the process from our control and discard all our state 476 */ 477 void 478 pctx_release(pctx_t *pctx) 479 { 480 if (pctx->Pr) { 481 Prelease(pctx->Pr, PRELEASE_CLEAR); 482 pctx->Pr = NULL; 483 } 484 485 pctx_free(pctx); 486 bzero(pctx, sizeof (*pctx)); 487 free(pctx); 488 } 489 490 static void 491 msincr(struct timeval *tv, uint_t msec) 492 { 493 tv->tv_sec += msec / MILLISEC; 494 tv->tv_usec += (msec % MILLISEC) * MILLISEC; 495 if (tv->tv_usec > MICROSEC) { 496 tv->tv_sec++; 497 tv->tv_usec -= MICROSEC; 498 } 499 } 500 501 static uint_t 502 msdiff(struct timeval *tva, struct timeval *tvb) 503 { 504 time_t sdiff = tva->tv_sec - tvb->tv_sec; 505 suseconds_t udiff = tva->tv_usec - tvb->tv_usec; 506 507 if (sdiff < 0) 508 return (0); 509 if (udiff < 0) { 510 udiff += MICROSEC; 511 sdiff--; 512 } 513 if (sdiff < 0) 514 return (0); 515 if (sdiff >= (INT_MAX / MILLISEC)) 516 return ((uint_t)INT_MAX); 517 return ((uint_t)(sdiff * MILLISEC + udiff / MILLISEC)); 518 } 519 520 int 521 pctx_run( 522 pctx_t *pctx, 523 uint_t msec, 524 uint_t nsamples, 525 int (*tick)(pctx_t *, pid_t, id_t, void *)) 526 { 527 static const char fn[] = "run"; 528 struct timeval tvgoal, tvnow; 529 uint_t mswait = 0; 530 int running = 1; 531 const pstatus_t *pstatus; 532 psinfo_t psinfo; 533 void (*sigsaved)(); 534 id_t lwpid; 535 pid_t pid = Pstatus(pctx->Pr)->pr_pid; 536 int pstate; 537 538 if (msec == 0) 539 nsamples = 0; 540 if (nsamples == 0) 541 nsamples = UINT_MAX; 542 543 /* 544 * Casually discard any knowledge of the children we create 545 */ 546 sigsaved = signal(SIGCHLD, SIG_IGN); 547 548 /* 549 * Since we've just "discovered" this process which might have 550 * been running for weeks, deliver some init_lwp events so 551 * that our caller gets a handle on the process. 552 */ 553 if (pctx_lwpiterate(pctx, pctx->init_lwp) != 0) { 554 if (pctx->verbose) 555 pctx_error(pctx, fn, 556 gettext("%d: lwp discovery failed\n"), (int)pid); 557 goto bailout; 558 } 559 560 if (msec != 0) { 561 /* 562 * tvgoal represents the time at which the sample 563 * should next be taken. 564 */ 565 (void) gettimeofday(&tvgoal, 0); 566 msincr(&tvgoal, msec); 567 } 568 569 /* 570 * The event handling loop continues while running is 1. 571 * running becomes 0 when either the controlled process has 572 * exited successfully or the number of time samples has expired. 573 * Otherwise, if an error has occurred, running becomes -1. 574 */ 575 while (running == 1 && !pctx->terminate) { 576 577 if (Psetrun(pctx->Pr, 0, 0) != 0) { 578 if (pctx->verbose) 579 pctx_error(pctx, fn, 580 gettext("%d: Psetrun\n"), (int)pid); 581 break; 582 } 583 584 if (msec != 0) { 585 /* 586 * This timing loop attempts to estimate the number 587 * of milliseconds between our "goal" time (when 588 * we should stop the process and run the tick 589 * routine) and the current time. 590 * 591 * If we ever find ourselves running behind i.e. we 592 * missed our goal, then we skip ahead to the next 593 * goal instead. 594 */ 595 do { 596 (void) gettimeofday(&tvnow, 0); 597 if ((mswait = msdiff(&tvgoal, &tvnow)) == 0) { 598 msincr(&tvgoal, msec); 599 /* 600 * Skip ahead to the next goal, unless 601 * there is only one more sample left 602 * to take. 603 */ 604 if (nsamples != 1) 605 nsamples--; 606 } 607 } while (mswait == 0 && !pctx->terminate); 608 } 609 610 if (pctx->terminate) 611 goto bailout; 612 else 613 (void) Pwait(pctx->Pr, mswait); 614 615 checkstate: 616 switch (pstate = Pstate(pctx->Pr)) { 617 case PS_RUN: 618 /* 619 * Try again, but wait for up to 5 seconds. 620 */ 621 if (Pstop(pctx->Pr, 5 * MILLISEC) == -1 || 622 (pstate = Pstate(pctx->Pr)) != PS_STOP) { 623 pctx_error(pctx, fn, 624 gettext("%d: won't stop\n"), (int)pid); 625 } 626 break; 627 case PS_STOP: 628 break; 629 case PS_LOST: 630 /* 631 * Lost control - probably execed a setuid/setgid 632 * executable. Try and get control back again, 633 * else bail .. 634 */ 635 (void) Preopen(pctx->Pr); 636 if ((pstate = Pstate(pctx->Pr)) != PS_LOST) 637 goto checkstate; 638 pctx_error(pctx, fn, 639 gettext("%d: execed a program that cannot " 640 "be tracked\n"), (int)pid); 641 running = -1; 642 break; 643 case PS_UNDEAD: 644 case PS_DEAD: 645 if (pctx->verbose) 646 pctx_error(pctx, fn, 647 gettext("%d: process terminated\n"), 648 (int)pid); 649 running = -1; 650 break; 651 default: 652 if (pctx->verbose) 653 pctx_error(pctx, fn, 654 gettext("%d: process state 0x%x?\n"), 655 (int)pid, pstate); 656 break; 657 } 658 659 if (pstate != PS_STOP) 660 break; 661 662 pstatus = Pstatus(pctx->Pr); 663 lwpid = pstatus->pr_lwp.pr_lwpid; 664 switch (pstatus->pr_lwp.pr_why) { 665 case PR_REQUESTED: 666 msincr(&tvgoal, msec); 667 if (pstatus->pr_flags & PR_VFORKP) { 668 /* 669 * The process is in a vfork stupor until 670 * its child releases it via an exec. 671 * Don't sample it while it's in this state 672 * - we won't be able to create the agent. 673 */ 674 break; 675 } 676 if (pctx_lwpiterate(pctx, tick) != 0) 677 running = -1; 678 if (running == 1 && --nsamples == 0) 679 running = 0; 680 break; 681 case PR_SYSENTRY: 682 switch (pstatus->pr_lwp.pr_what) { 683 case SYS_lwp_exit: 684 pctx_begin_syscalls(pctx); 685 (void) pctx->fini_lwp(pctx, 686 pid, lwpid, pctx->uarg); 687 (void) pctx->lwp_exit(pctx, 688 pid, lwpid, pctx->uarg); 689 pctx_end_syscalls(pctx); 690 break; 691 case SYS_exit: 692 if (pctx_lwpiterate(pctx, pctx->fini_lwp) 693 != 0) 694 running = -1; 695 pctx->exit(pctx, pid, lwpid, 696 (int)pstatus->pr_lwp.pr_sysarg[0], 697 pctx->uarg); 698 if (running == 1) 699 running = 0; 700 break; 701 case SYS_execve: 702 (void) pctx_lwpiterate(pctx, pctx->fini_lwp); 703 break; 704 default: 705 pctx_error(pctx, fn, 706 "warning - pid %d sysentry(%d)\n", 707 (int)pid, pstatus->pr_lwp.pr_what); 708 break; 709 } 710 break; 711 case PR_SYSEXIT: 712 switch (pstatus->pr_lwp.pr_what) { 713 case SYS_execve: 714 if (pstatus->pr_lwp.pr_errno) { 715 /* 716 * The exec failed completely. 717 * Reinstate the lwps we fini'd 718 * at exec entrance 719 */ 720 if (pctx_lwpiterate(pctx, 721 pctx->init_lwp) == 0) 722 running = 1; 723 else 724 running = -1; 725 break; 726 } 727 if ((uintptr_t)pctx->exec == 728 (uintptr_t)default_int) { 729 running = 0; 730 break; 731 } 732 (void) memcpy(&psinfo, 733 Ppsinfo(pctx->Pr), sizeof (psinfo)); 734 proc_unctrl_psinfo(&psinfo); 735 pctx_begin_syscalls(pctx); 736 if (pctx->exec(pctx, pid, lwpid, 737 psinfo.pr_psargs, pctx->uarg) != 0) 738 running = -1; 739 if (running == 1 && pctx->init_lwp(pctx, 740 pid, 1, pctx->uarg) != 0) 741 running = -1; 742 pctx_end_syscalls(pctx); 743 break; 744 case SYS_lwp_create: 745 if (pstatus->pr_lwp.pr_errno || 746 pstatus->pr_lwp.pr_rval1) 747 break; 748 pctx_begin_syscalls(pctx); 749 if (pctx->init_lwp(pctx, pid, lwpid, 750 pctx->uarg) != 0) 751 running = -1; 752 if (running == 1 && pctx->lwp_create(pctx, 753 pid, lwpid, pctx->uarg) != 0) 754 running = -1; 755 pctx_end_syscalls(pctx); 756 break; 757 case SYS_vfork: 758 case SYS_forksys: 759 if (pstatus->pr_lwp.pr_errno) 760 break; 761 (void) fflush(NULL); 762 switch (fork1()) { 763 pid_t ppid; 764 int wascreated; 765 pctx_sysc_forkfn_t *forkfn; 766 case 0: 767 ppid = pid; 768 pid = pstatus->pr_lwp.pr_rval1; 769 wascreated = pctx->created; 770 forkfn = pctx->fork; 771 pctx_free(pctx); 772 pctx = pctx_capture(pid, pctx->uarg, 773 pctx->verbose, pctx->errfn); 774 if (pctx != NULL) { 775 if (wascreated) { 776 /* 777 * Set kill on last 778 * close so -all- 779 * children die. 780 */ 781 pctx->created = 1; 782 (void) Psetflags( 783 pctx->Pr, PR_KLC); 784 } 785 (*forkfn)(pctx, ppid, pid, 786 lwpid, pctx->uarg); 787 pctx_release(pctx); 788 _exit(0); 789 } else { 790 _exit(1); 791 } 792 /*NOTREACHED*/ 793 case -1: 794 pctx_error(pctx, fn, 795 "cannot follow pid %d: %s\n", 796 (int)pstatus->pr_lwp.pr_rval1, 797 strerror(errno)); 798 break; 799 default: 800 break; 801 } 802 break; 803 default: 804 pctx_error(pctx, fn, gettext( 805 "warning - pid %d sysexit(%d)\n"), 806 (int)pid, pstatus->pr_lwp.pr_what); 807 break; 808 } 809 break; 810 case PR_SIGNALLED: 811 if (pctx->verbose) 812 pctx_error(pctx, fn, 813 gettext("pid %d - signalled\n"), (int)pid); 814 break; 815 case PR_JOBCONTROL: 816 if (pctx->verbose) 817 pctx_error(pctx, fn, 818 gettext("pid %d - job control stop\n"), 819 (int)pid); 820 running = -1; 821 break; 822 case PR_FAULTED: 823 if (pctx->verbose) 824 pctx_error(pctx, fn, 825 gettext("pid %d - faulted\n"), (int)pid); 826 break; 827 case PR_SUSPENDED: 828 if (pctx->verbose) 829 pctx_error(pctx, fn, 830 gettext("pid %d - suspended\n"), (int)pid); 831 break; 832 case PR_CHECKPOINT: 833 if (pctx->verbose) 834 pctx_error(pctx, fn, 835 gettext("pid %d - checkpoint\n"), 836 (int)pid); 837 break; 838 default: 839 if (pctx->verbose) 840 pctx_error(pctx, fn, 841 gettext("pid %d - reason %d\n"), 842 (int)pid, pstatus->pr_lwp.pr_why); 843 running = -1; 844 break; 845 } 846 } 847 848 bailout: 849 (void) signal(SIGCHLD, sigsaved); 850 851 if (pctx->terminate) 852 return (0); 853 854 switch (running) { 855 case 0: 856 return (0); 857 case -1: 858 return (-1); 859 default: 860 pctx_error(pctx, fn, gettext("lost control of pid %d\n"), 861 (int)pid); 862 pctx_free(pctx); 863 return (-1); 864 } 865 } 866 867 /* 868 * Execute the private 'cpc' system call in the context of the 869 * controlled process. 870 */ 871 int 872 __pctx_cpc(pctx_t *pctx, cpc_t *cpc, 873 int cmd, id_t lwpid, void *data1, void *data2, void *data3, int bufsize) 874 { 875 sysret_t rval; 876 argdes_t argd[5]; 877 argdes_t *adp = &argd[0]; 878 int error; 879 880 /* 881 * Keep track of the relationship between cpc_t and pctx_t here. 882 * We store the last cpc_t used by libpctx, so that when this pctx is 883 * destroyed, libpctx can notify libcpc. 884 */ 885 886 if (pctx->cpc != NULL && pctx->cpc != cpc && pctx_cpc_callback != NULL) 887 (*pctx_cpc_callback)(pctx->cpc, pctx); 888 pctx->cpc = cpc; 889 890 /* 891 * cmd and lwpid are passed in by value no matter what the command is. 892 */ 893 adp->arg_value = cmd; 894 adp->arg_object = NULL; 895 adp->arg_type = AT_BYVAL; 896 adp->arg_inout = AI_INPUT; 897 adp->arg_size = 0; 898 adp++; 899 900 adp->arg_value = lwpid; 901 adp->arg_object = NULL; 902 adp->arg_type = AT_BYVAL; 903 adp->arg_inout = AI_INPUT; 904 adp->arg_size = 0; 905 adp++; 906 907 switch (cmd) { 908 case CPC_BIND: 909 adp->arg_value = 0; 910 adp->arg_object = data1; 911 adp->arg_type = AT_BYREF; 912 adp->arg_inout = AI_INPUT; 913 adp->arg_size = (size_t)data2; 914 adp++; 915 916 adp->arg_value = (size_t)data2; 917 adp->arg_object = NULL; 918 adp->arg_type = AT_BYVAL; 919 adp->arg_inout = AI_INPUT; 920 adp->arg_size = 0; 921 adp++; 922 923 adp->arg_value = 0; 924 adp->arg_object = data3; 925 adp->arg_type = AT_BYREF; 926 adp->arg_inout = AI_INOUT; 927 adp->arg_size = sizeof (int); 928 929 break; 930 case CPC_SAMPLE: 931 adp->arg_value = 0; 932 adp->arg_object = data1; 933 adp->arg_type = AT_BYREF; 934 adp->arg_inout = AI_OUTPUT; 935 adp->arg_size = bufsize; 936 adp++; 937 938 adp->arg_value = 0; 939 adp->arg_object = data2; 940 adp->arg_type = AT_BYREF; 941 adp->arg_inout = AI_OUTPUT; 942 adp->arg_size = sizeof (hrtime_t); 943 adp++; 944 945 adp->arg_value = 0; 946 adp->arg_object = data3; 947 adp->arg_type = AT_BYREF; 948 adp->arg_inout = AI_OUTPUT; 949 adp->arg_size = sizeof (uint64_t); 950 951 break; 952 default: 953 adp->arg_value = 0; 954 adp->arg_object = 0; 955 adp->arg_type = AT_BYVAL; 956 adp->arg_inout = AI_INPUT; 957 adp->arg_size = 0; 958 adp++; 959 960 adp->arg_value = 0; 961 adp->arg_object = 0; 962 adp->arg_type = AT_BYVAL; 963 adp->arg_inout = AI_INPUT; 964 adp->arg_size = 0; 965 adp++; 966 967 adp->arg_value = 0; 968 adp->arg_object = 0; 969 adp->arg_type = AT_BYVAL; 970 adp->arg_inout = AI_INPUT; 971 adp->arg_size = 0; 972 973 break; 974 } 975 976 error = Psyscall(pctx->Pr, &rval, SYS_cpc, 5, &argd[0]); 977 978 if (error) { 979 errno = error > 0 ? error : ENOSYS; 980 return (-1); 981 } 982 return (rval.sys_rval1); 983 } 984 985 /* 986 * libcpc-private hook used to register a callback. The callback is used to 987 * notify libcpc when a pctx handle is invalidated. 988 */ 989 void 990 __pctx_cpc_register_callback(void (*arg)(struct __cpc *, struct __pctx *)) 991 { 992 pctx_cpc_callback = arg; 993 } 994 995 /* 996 * Tell pctx_run to bail out immediately 997 */ 998 void 999 pctx_terminate(struct __pctx *pctx) 1000 { 1001 pctx->terminate = 1; 1002 } 1003