2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * This file contains a set of generic routines for periodically 2N/A * sampling the state of another process, or tree of processes. 2N/A * It is built upon the infrastructure provided by libproc. 2N/A * Create a new process and bind the user args for it 2N/A static const char fn[] =
"create";
2N/A * Set kill-on-last-close so the controlled process 2N/A * Capture an existing process and bind the user args for it 2N/A static const char fn[] =
"capture";
2N/A "process, pid %d\n"), (
int)
pid);
2N/A * Set run-on-last-close so the controlled process 2N/A * runs even if we die on a signal. This is because 2N/A * we grabbed an existing process - it would be impolite 2N/A * to cause it to die if we exit prematurely. 2N/A static const char fn[] =
"set_events";
2N/A * exec causes termination of all but the exec-ing lwp, 2N/A * and resets the lwpid to one in the new address space. 2N/A * Initialize the signal set used to shield ourselves from 2N/A * death-by-terminal-signal while the agent lwp is running. 2N/A * Iterate over the valid lwpids in the process, invoking the 2N/A * action function on each one. 2N/A /* LINTED pointer cast may result in improper alignment */ 2N/A /* LINTED pointer cast may result in improper alignment */ 2N/A * Free any associated state, but leave the process stopped if it 2N/A * is still under our control. (If it isn't under our control, 2N/A * it should just run to completion when we do our last close) 2N/A * Completely release the process from our control and discard all our state 2N/A static const char fn[] =
"run";
2N/A * Casually discard any knowledge of the children we create 2N/A * Since we've just "discovered" this process which might have 2N/A * been running for weeks, deliver some init_lwp events so 2N/A * that our caller gets a handle on the process. 2N/A * tvgoal represents the time at which the sample 2N/A * should next be taken. 2N/A * The event handling loop continues while running is 1. 2N/A * running becomes 0 when either the controlled process has 2N/A * exited successfully or the number of time samples has expired. 2N/A * Otherwise, if an error has occurred, running becomes -1. 2N/A * This timing loop attempts to estimate the number 2N/A * of milliseconds between our "goal" time (when 2N/A * we should stop the process and run the tick 2N/A * routine) and the current time. 2N/A * If we ever find ourselves running behind i.e. we 2N/A * missed our goal, then we skip ahead to the next 2N/A * Skip ahead to the next goal, unless 2N/A * there is only one more sample left 2N/A * Try again, but wait for up to 5 seconds. 2N/A * executable. Try and get control back again, 2N/A * The process is in a vfork stupor until 2N/A * its child releases it via an exec. 2N/A * Don't sample it while it's in this state 2N/A * - we won't be able to create the agent. 2N/A "warning - pid %d sysentry(%d)\n",
2N/A * The exec failed completely. 2N/A * Reinstate the lwps we fini'd 2N/A "cannot follow pid %d: %s\n",
2N/A "warning - pid %d sysexit(%d)\n"),
2N/A * Execute the private 'cpc' system call in the context of the 2N/A * controlled process. 2N/A * Keep track of the relationship between cpc_t and pctx_t here. 2N/A * We store the last cpc_t used by libpctx, so that when this pctx is 2N/A * destroyed, libpctx can notify libcpc. 2N/A * cmd and lwpid are passed in by value no matter what the command is. 2N/A * libcpc-private hook used to register a callback. The callback is used to 2N/A * notify libcpc when a pctx handle is invalidated. 2N/A * Tell pctx_run to bail out immediately