Home | History | Annotate | Download | only in truss
      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 2007 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 
     29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     30 
     31 #include <stdio.h>
     32 #include <stdio_ext.h>
     33 #include <stdlib.h>
     34 #include <unistd.h>
     35 #include <fcntl.h>
     36 #include <ctype.h>
     37 #include <string.h>
     38 #include <memory.h>
     39 #include <signal.h>
     40 #include <wait.h>
     41 #include <limits.h>
     42 #include <errno.h>
     43 #include <sys/types.h>
     44 #include <sys/time.h>
     45 #include <sys/times.h>
     46 #include <sys/fstyp.h>
     47 #include <sys/fsid.h>
     48 #include <sys/stat.h>
     49 #include <sys/mman.h>
     50 #include <sys/resource.h>
     51 #include <libproc.h>
     52 #include "ramdata.h"
     53 #include "proto.h"
     54 #include "htbl.h"
     55 
     56 /*
     57  * The user can trace individual threads by using the 'pid/1,3-6,8-' syntax.
     58  * This structure keeps track of pid/lwp specifications.  If there are no LWPs
     59  * specified, then 'lwps' will be NULL.
     60  */
     61 typedef struct proc_set {
     62 	pid_t		pid;
     63 	const char 	*lwps;
     64 } proc_set_t;
     65 
     66 /*
     67  * Function prototypes for static routines in this file.
     68  */
     69 void	setup_basetime(hrtime_t, struct timeval *);
     70 int	xcreat(char *);
     71 void	setoutput(int);
     72 void	report(private_t *, time_t);
     73 void	prtim(timestruc_t *);
     74 void	pids(char *, proc_set_t *);
     75 void	psargs(private_t *);
     76 int	control(private_t *, pid_t);
     77 int	grabit(private_t *, proc_set_t *);
     78 void	release(private_t *, pid_t);
     79 void	intr(int);
     80 int	wait4all(void);
     81 void	letgo(private_t *);
     82 void	child_to_file();
     83 void	file_to_parent();
     84 void	per_proc_init();
     85 int	lib_sort(const void *, const void *);
     86 int	key_sort(const void *, const void *);
     87 
     88 void	*worker_thread(void *);
     89 void	main_thread(int);
     90 
     91 /*
     92  * Test for empty set.
     93  * is_empty() should not be called directly.
     94  */
     95 int	is_empty(const uint32_t *, size_t);
     96 #define	isemptyset(sp) \
     97 	is_empty((uint32_t *)(sp), sizeof (*(sp)) / sizeof (uint32_t))
     98 
     99 /*
    100  * OR the second set into the first set.
    101  * or_set() should not be called directly.
    102  */
    103 void	or_set(uint32_t *, const uint32_t *, size_t);
    104 #define	prorset(sp1, sp2) \
    105 	or_set((uint32_t *)(sp1), (uint32_t *)(sp2), \
    106 	sizeof (*(sp1)) / sizeof (uint32_t))
    107 
    108 /* fetch or allocate thread-private data */
    109 private_t *
    110 get_private()
    111 {
    112 	void *value;
    113 	private_t *pri = NULL;
    114 
    115 	if (thr_getspecific(private_key, &value) == 0)
    116 		pri = value;
    117 	if (pri == NULL) {
    118 		pri = my_malloc(sizeof (*pri), NULL);
    119 		(void) memset(pri, 0, sizeof (*pri));
    120 		pri->sys_path = my_malloc(pri->sys_psize = 16, NULL);
    121 		pri->sys_string = my_malloc(pri->sys_ssize = 32, NULL);
    122 		if (thr_setspecific(private_key, pri) == ENOMEM)
    123 			abend("memory allocation failure", NULL);
    124 	}
    125 	return (pri);
    126 }
    127 
    128 /* destructor function for thread-private data */
    129 void
    130 free_private(void *value)
    131 {
    132 	private_t *pri = value;
    133 
    134 	if (pri->sys_path)
    135 		free(pri->sys_path);
    136 	if (pri->sys_string)
    137 		free(pri->sys_string);
    138 	if (pri->exec_string)
    139 		free(pri->exec_string);
    140 	if (pri->str_buffer)
    141 		free(pri->str_buffer);
    142 	free(pri);
    143 }
    144 
    145 /*
    146  * This is called by the main thread (via create_thread())
    147  * and is also called from other threads in worker_thread()
    148  * while holding truss_lock.  No further locking is required.
    149  */
    150 void
    151 insert_lwpid(lwpid_t lwpid)
    152 {
    153 	int i;
    154 
    155 	truss_nlwp++;
    156 	for (i = 0; i < truss_maxlwp; i++) {
    157 		if (truss_lwpid[i] == 0)
    158 			break;
    159 	}
    160 	if (i == truss_maxlwp) {
    161 		/* double the size of the array */
    162 		truss_lwpid = my_realloc(truss_lwpid,
    163 			truss_maxlwp * 2 * sizeof (lwpid_t), NULL);
    164 		(void) memset(&truss_lwpid[truss_maxlwp], 0,
    165 			truss_maxlwp * sizeof (lwpid_t));
    166 		truss_maxlwp *= 2;
    167 	}
    168 	truss_lwpid[i] = lwpid;
    169 }
    170 
    171 /*
    172  * This is called from the first worker thread to encounter one of
    173  * (leave_hung || interrupt || sigusr1).  It must notify all other
    174  * worker threads of the same condition.  truss_lock is held.
    175  */
    176 void
    177 broadcast_signals(void)
    178 {
    179 	static int int_notified = FALSE;
    180 	static int usr1_notified = FALSE;
    181 	static int usr2_notified = FALSE;
    182 	lwpid_t my_id = thr_self();
    183 	lwpid_t lwpid;
    184 	int i;
    185 
    186 	if (interrupt && !int_notified) {
    187 		int_notified = TRUE;
    188 		for (i = 0; i < truss_maxlwp; i++) {
    189 			if ((lwpid = truss_lwpid[i]) != 0 && lwpid != my_id)
    190 				(void) thr_kill(lwpid, interrupt);
    191 		}
    192 	}
    193 	if (sigusr1 && !usr1_notified) {
    194 		usr1_notified = TRUE;
    195 		for (i = 0; i < truss_maxlwp; i++) {
    196 			if ((lwpid = truss_lwpid[i]) != 0 && lwpid != my_id)
    197 				(void) thr_kill(lwpid, SIGUSR1);
    198 		}
    199 	}
    200 	if (leave_hung && !usr2_notified) {
    201 		usr2_notified = TRUE;
    202 		for (i = 0; i < truss_maxlwp; i++) {
    203 			if ((lwpid = truss_lwpid[i]) != 0 && lwpid != my_id)
    204 				(void) thr_kill(lwpid, SIGUSR2);
    205 		}
    206 	}
    207 }
    208 
    209 static struct ps_lwphandle *
    210 grab_lwp(lwpid_t who)
    211 {
    212 	struct ps_lwphandle *Lwp;
    213 	int gcode;
    214 
    215 	if ((Lwp = Lgrab(Proc, who, &gcode)) == NULL) {
    216 		if (gcode != G_NOPROC) {
    217 			(void) fprintf(stderr,
    218 				"%s: cannot grab LWP %u in process %d,"
    219 				" reason: %s\n",
    220 				command, who, (int)Pstatus(Proc)->pr_pid,
    221 				Lgrab_error(gcode));
    222 			interrupt = SIGTERM;	/* post an interrupt */
    223 		}
    224 	}
    225 	return (Lwp);
    226 }
    227 
    228 /*
    229  * Iteration function called for each initial lwp in the controlled process.
    230  */
    231 /* ARGSUSED */
    232 int
    233 create_thread(void *arg, const lwpstatus_t *Lsp)
    234 {
    235 	struct ps_lwphandle *new_Lwp;
    236 	lwpid_t lwpid;
    237 	int *count = arg;
    238 
    239 	if (lwptrace(Pstatus(Proc)->pr_pid, Lsp->pr_lwpid))
    240 		*count += 1;
    241 
    242 	if ((new_Lwp = grab_lwp(Lsp->pr_lwpid)) != NULL) {
    243 		if (thr_create(NULL, 0, worker_thread, new_Lwp,
    244 		    THR_BOUND | THR_SUSPENDED, &lwpid) != 0)
    245 			abend("cannot create lwp to follow child lwp", NULL);
    246 		insert_lwpid(lwpid);
    247 	}
    248 	return (0);
    249 }
    250 
    251 int
    252 main(int argc, char *argv[])
    253 {
    254 	private_t *pri;
    255 	struct tms tms;
    256 	struct rlimit rlim;
    257 	int ofd = -1;
    258 	int opt;
    259 	int i;
    260 	int first;
    261 	int errflg = FALSE;
    262 	int badname = FALSE;
    263 	proc_set_t *grab = NULL;
    264 	const pstatus_t *Psp;
    265 	const lwpstatus_t *Lsp;
    266 	int sharedmem;
    267 
    268 	/* a few of these need to be initialized to NULL */
    269 	Cp = NULL;
    270 	fcall_tbl = NULL;
    271 
    272 	/*
    273 	 * Make sure fd's 0, 1, and 2 are allocated,
    274 	 * just in case truss was invoked from init.
    275 	 */
    276 	while ((i = open("/dev/null", O_RDWR)) >= 0 && i < 2)
    277 		;
    278 	if (i > 2)
    279 		(void) close(i);
    280 
    281 	starttime = times(&tms);	/* for elapsed timing */
    282 
    283 	/* this should be per-traced-process */
    284 	pagesize = sysconf(_SC_PAGESIZE);
    285 
    286 	/* command name (e.g., "truss") */
    287 	if ((command = strrchr(argv[0], '/')) != NULL)
    288 		command++;
    289 	else
    290 		command = argv[0];
    291 
    292 	/* set up the initial private data */
    293 	(void) mutex_init(&truss_lock, USYNC_THREAD, NULL);
    294 	(void) mutex_init(&count_lock, USYNC_THREAD, NULL);
    295 	(void) cond_init(&truss_cv, USYNC_THREAD, NULL);
    296 	if (thr_keycreate(&private_key, free_private) == ENOMEM)
    297 		abend("memory allocation failure", NULL);
    298 	pri = get_private();
    299 
    300 	Euid = geteuid();
    301 	Egid = getegid();
    302 	Ruid = getuid();
    303 	Rgid = getgid();
    304 	ancestor = getpid();
    305 
    306 	prfillset(&trace);	/* default: trace all system calls */
    307 	premptyset(&verbose);	/* default: no syscall verbosity */
    308 	premptyset(&rawout);	/* default: no raw syscall interpretation */
    309 
    310 	prfillset(&signals);	/* default: trace all signals */
    311 
    312 	prfillset(&faults);	/* default: trace all faults */
    313 	prdelset(&faults, FLTPAGE);	/* except this one */
    314 
    315 	premptyset(&readfd);	/* default: dump no buffers */
    316 	premptyset(&writefd);
    317 
    318 	premptyset(&syshang);	/* default: hang on no system calls */
    319 	premptyset(&sighang);	/* default: hang on no signals */
    320 	premptyset(&flthang);	/* default: hang on no faults */
    321 
    322 	(void) sigemptyset(&emptyset);	/* for unblocking all signals */
    323 	(void) sigfillset(&fillset);	/* for blocking all signals */
    324 
    325 #define	OPTIONS	"FpfcaeildDEht:T:v:x:s:S:m:M:u:U:r:w:o:"
    326 	while ((opt = getopt(argc, argv, OPTIONS)) != EOF) {
    327 		switch (opt) {
    328 		case 'F':		/* force grabbing (no O_EXCL) */
    329 			Fflag = PGRAB_FORCE;
    330 			break;
    331 		case 'p':		/* grab processes */
    332 			pflag = TRUE;
    333 			break;
    334 		case 'f':		/* follow children */
    335 			fflag = TRUE;
    336 			break;
    337 		case 'c':		/* don't trace, just count */
    338 			cflag = TRUE;
    339 			iflag = TRUE;	/* implies no interruptable syscalls */
    340 			break;
    341 		case 'a':		/* display argument lists */
    342 			aflag = TRUE;
    343 			break;
    344 		case 'e':		/* display environments */
    345 			eflag = TRUE;
    346 			break;
    347 		case 'i':		/* don't show interruptable syscalls */
    348 			iflag = TRUE;
    349 			break;
    350 		case 'l':		/* show lwp id for each syscall */
    351 			lflag = TRUE;
    352 			break;
    353 		case 'h':		/* debugging: report hash stats */
    354 			hflag = TRUE;
    355 			break;
    356 		case 'd':		/* show time stamps */
    357 			dflag = TRUE;
    358 			break;
    359 		case 'D':		/* show time deltas */
    360 			Dflag = TRUE;
    361 			break;
    362 		case 'E':
    363 			Eflag = TRUE;	/* show syscall times */
    364 			break;
    365 		case 't':		/* system calls to trace */
    366 			if (syslist(optarg, &trace, &tflag))
    367 				badname = TRUE;
    368 			break;
    369 		case 'T':		/* system calls to hang process */
    370 			if (syslist(optarg, &syshang, &Tflag))
    371 				badname = TRUE;
    372 			break;
    373 		case 'v':		/* verbose interpretation of syscalls */
    374 			if (syslist(optarg, &verbose, &vflag))
    375 				badname = TRUE;
    376 			break;
    377 		case 'x':		/* raw interpretation of syscalls */
    378 			if (syslist(optarg, &rawout, &xflag))
    379 				badname = TRUE;
    380 			break;
    381 		case 's':		/* signals to trace */
    382 			if (siglist(pri, optarg, &signals, &sflag))
    383 				badname = TRUE;
    384 			break;
    385 		case 'S':		/* signals to hang process */
    386 			if (siglist(pri, optarg, &sighang, &Sflag))
    387 				badname = TRUE;
    388 			break;
    389 		case 'm':		/* machine faults to trace */
    390 			if (fltlist(optarg, &faults, &mflag))
    391 				badname = TRUE;
    392 			break;
    393 		case 'M':		/* machine faults to hang process */
    394 			if (fltlist(optarg, &flthang, &Mflag))
    395 				badname = TRUE;
    396 			break;
    397 		case 'u':		/* user library functions to trace */
    398 			if (liblist(optarg, 0))
    399 				badname = TRUE;
    400 			break;
    401 		case 'U':		/* user library functions to hang */
    402 			if (liblist(optarg, 1))
    403 				badname = TRUE;
    404 			break;
    405 		case 'r':		/* show contents of read(fd) */
    406 			if (fdlist(optarg, &readfd))
    407 				badname = TRUE;
    408 			break;
    409 		case 'w':		/* show contents of write(fd) */
    410 			if (fdlist(optarg, &writefd))
    411 				badname = TRUE;
    412 			break;
    413 		case 'o':		/* output file for trace */
    414 			oflag = TRUE;
    415 			if (ofd >= 0)
    416 				(void) close(ofd);
    417 			if ((ofd = xcreat(optarg)) < 0) {
    418 				perror(optarg);
    419 				badname = TRUE;
    420 			}
    421 			break;
    422 		default:
    423 			errflg = TRUE;
    424 			break;
    425 		}
    426 	}
    427 
    428 	if (badname)
    429 		exit(2);
    430 
    431 	/* if -a or -e was specified, force tracing of exec() */
    432 	if (aflag || eflag) {
    433 		praddset(&trace, SYS_exec);
    434 		praddset(&trace, SYS_execve);
    435 	}
    436 
    437 	/*
    438 	 * Make sure that all system calls, signals, and machine faults
    439 	 * that hang the process are added to their trace sets.
    440 	 */
    441 	prorset(&trace, &syshang);
    442 	prorset(&signals, &sighang);
    443 	prorset(&faults, &flthang);
    444 
    445 	argc -= optind;
    446 	argv += optind;
    447 
    448 	/* collect the specified process ids */
    449 	if (pflag && argc > 0) {
    450 		grab = my_malloc(argc * sizeof (proc_set_t),
    451 			"memory for process-ids");
    452 		while (argc-- > 0)
    453 			pids(*argv++, grab);
    454 	}
    455 
    456 	if (errflg || (argc <= 0 && ngrab <= 0)) {
    457 		(void) fprintf(stderr,
    458 	"usage:\t%s [-fcaeildDEF] [-[tTvx] [!]syscalls] [-[sS] [!]signals]\\\n",
    459 			command);
    460 		(void) fprintf(stderr,
    461 	"\t[-[mM] [!]faults] [-[rw] [!]fds] [-[uU] [!]libs:[:][!]funcs]\\\n");
    462 		(void) fprintf(stderr,
    463 	"\t[-o outfile]  command | -p pid[/lwps] ...\n");
    464 		exit(2);
    465 	}
    466 
    467 	if (argc > 0) {		/* create the controlled process */
    468 		int err;
    469 		char path[PATH_MAX];
    470 
    471 		Proc = Pcreate(argv[0], &argv[0], &err, path, sizeof (path));
    472 		if (Proc == NULL) {
    473 			switch (err) {
    474 			case C_PERM:
    475 				(void) fprintf(stderr,
    476 					"%s: cannot trace set-id or "
    477 					"unreadable object file: %s\n",
    478 					command, path);
    479 				break;
    480 			case C_LP64:
    481 				(void) fprintf(stderr,
    482 					"%s: cannot control _LP64 "
    483 					"program: %s\n",
    484 					command, path);
    485 				break;
    486 			case C_NOEXEC:
    487 				(void) fprintf(stderr,
    488 					"%s: cannot execute program: %s\n",
    489 					command, argv[0]);
    490 				break;
    491 			case C_NOENT:
    492 				(void) fprintf(stderr,
    493 					"%s: cannot find program: %s\n",
    494 					command, argv[0]);
    495 				break;
    496 			case C_STRANGE:
    497 				break;
    498 			default:
    499 				(void) fprintf(stderr, "%s: %s\n",
    500 					command, Pcreate_error(err));
    501 				break;
    502 			}
    503 			exit(2);
    504 		}
    505 		if (fflag || Dynpat != NULL)
    506 			(void) Psetflags(Proc, PR_FORK);
    507 		else
    508 			(void) Punsetflags(Proc, PR_FORK);
    509 		Psp = Pstatus(Proc);
    510 		Lsp = &Psp->pr_lwp;
    511 		pri->lwpstat = Lsp;
    512 		data_model = Psp->pr_dmodel;
    513 		created = Psp->pr_pid;
    514 		make_pname(pri, 0);
    515 		(void) sysentry(pri, 1);
    516 		pri->length = 0;
    517 		if (!cflag && prismember(&trace, SYS_execve)) {
    518 			pri->exec_string = my_realloc(pri->exec_string,
    519 				strlen(pri->sys_string) + 1, NULL);
    520 			(void) strcpy(pri->exec_pname, pri->pname);
    521 			(void) strcpy(pri->exec_string, pri->sys_string);
    522 			pri->length += strlen(pri->sys_string);
    523 			pri->exec_lwpid = pri->lwpstat->pr_lwpid;
    524 			pri->sys_leng = 0;
    525 			*pri->sys_string = '\0';
    526 		}
    527 		pri->syslast = Psp->pr_stime;
    528 		pri->usrlast = Psp->pr_utime;
    529 	}
    530 
    531 	/*
    532 	 * Now that we have created the victim process,
    533 	 * give ourself a million file descriptors.
    534 	 * This is enough to deal with a multithreaded
    535 	 * victim process that has half a million lwps.
    536 	 */
    537 	rlim.rlim_cur = 1024 * 1024;
    538 	rlim.rlim_max = 1024 * 1024;
    539 	if ((Euid != 0 || setrlimit(RLIMIT_NOFILE, &rlim) != 0) &&
    540 	    getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
    541 		/*
    542 		 * Failing the million, give ourself as many
    543 		 * file descriptors as we can get.
    544 		 */
    545 		rlim.rlim_cur = rlim.rlim_max;
    546 		(void) setrlimit(RLIMIT_NOFILE, &rlim);
    547 	}
    548 	(void) enable_extended_FILE_stdio(-1, -1);
    549 
    550 	setoutput(ofd);		/* establish truss output */
    551 	istty = isatty(1);
    552 
    553 	if (setvbuf(stdout, (char *)NULL, _IOFBF, MYBUFSIZ) != 0)
    554 		abend("setvbuf() failure", NULL);
    555 
    556 	/*
    557 	 * Set up signal dispositions.
    558 	 */
    559 	if (created && (oflag || !istty)) {	/* ignore interrupts */
    560 		(void) sigset(SIGHUP, SIG_IGN);
    561 		(void) sigset(SIGINT, SIG_IGN);
    562 		(void) sigset(SIGQUIT, SIG_IGN);
    563 	} else {				/* receive interrupts */
    564 		if (sigset(SIGHUP, SIG_IGN) == SIG_DFL)
    565 			(void) sigset(SIGHUP, intr);
    566 		if (sigset(SIGINT, SIG_IGN) == SIG_DFL)
    567 			(void) sigset(SIGINT, intr);
    568 		if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL)
    569 			(void) sigset(SIGQUIT, intr);
    570 	}
    571 	(void) sigset(SIGTERM, intr);
    572 	(void) sigset(SIGUSR1, intr);
    573 	(void) sigset(SIGUSR2, intr);
    574 	(void) sigset(SIGPIPE, intr);
    575 
    576 	/* don't accumulate zombie children */
    577 	(void) sigset(SIGCLD, SIG_IGN);
    578 
    579 	/* create shared mem space for global mutexes */
    580 
    581 	sharedmem = (fflag || Dynpat != NULL || ngrab > 1);
    582 	gps = (void *)mmap(NULL, sizeof (struct global_psinfo),
    583 	    PROT_READ|PROT_WRITE,
    584 	    MAP_ANON | (sharedmem? MAP_SHARED : MAP_PRIVATE),
    585 	    -1, (off_t)0);
    586 	if (gps == MAP_FAILED)
    587 		abend("cannot allocate ", "memory for counts");
    588 	i = sharedmem? USYNC_PROCESS : USYNC_THREAD;
    589 	(void) mutex_init(&gps->ps_mutex0, i, NULL);
    590 	(void) mutex_init(&gps->ps_mutex1, i, NULL);
    591 	(void) mutex_init(&gps->fork_lock, i, NULL);
    592 	(void) cond_init(&gps->fork_cv, i, NULL);
    593 
    594 
    595 	/* config tmp file if counting and following */
    596 	if (fflag && cflag) {
    597 		char *tmps = tempnam("/var/tmp", "truss");
    598 		sfd = open(tmps, O_CREAT|O_APPEND|O_EXCL|O_RDWR, 0600);
    599 		if (sfd == -1)
    600 			abend("Error creating tmpfile", NULL);
    601 		if (unlink(tmps) == -1)
    602 			abend("Error unlinking tmpfile", NULL);
    603 		free(tmps);
    604 		tmps = NULL;
    605 	}
    606 
    607 	if (created) {
    608 		per_proc_init();
    609 		procadd(created, NULL);
    610 		show_cred(pri, TRUE);
    611 	} else {		/* grab the specified processes */
    612 		int gotone = FALSE;
    613 
    614 		i = 0;
    615 		while (i < ngrab) {		/* grab first process */
    616 			if (grabit(pri, &grab[i++])) {
    617 				Psp = Pstatus(Proc);
    618 				Lsp = &Psp->pr_lwp;
    619 				gotone = TRUE;
    620 				break;
    621 			}
    622 		}
    623 		if (!gotone)
    624 			abend(NULL, NULL);
    625 		per_proc_init();
    626 		while (i < ngrab) {		/* grab the remainder */
    627 			proc_set_t *set = &grab[i++];
    628 
    629 			(void) mutex_lock(&truss_lock);
    630 			switch (fork()) {
    631 			case -1:
    632 				(void) fprintf(stderr,
    633 			"%s: cannot fork to control process, pid# %d\n",
    634 					command, (int)set->pid);
    635 				/* FALLTHROUGH */
    636 			default:
    637 				(void) mutex_unlock(&truss_lock);
    638 				continue;	/* parent carries on */
    639 
    640 			case 0:			/* child grabs process */
    641 				(void) mutex_unlock(&truss_lock);
    642 				Pfree(Proc);
    643 				descendent = TRUE;
    644 				if (grabit(pri, set)) {
    645 					Psp = Pstatus(Proc);
    646 					Lsp = &Psp->pr_lwp;
    647 					per_proc_init();
    648 					break;
    649 				}
    650 				exit(2);
    651 			}
    652 			break;
    653 		}
    654 		free(grab);
    655 	}
    656 
    657 
    658 	/*
    659 	 * If running setuid-root, become root for real to avoid
    660 	 * affecting the per-user limitation on the maximum number
    661 	 * of processes (one benefit of running setuid-root).
    662 	 */
    663 	if (Rgid != Egid)
    664 		(void) setgid(Egid);
    665 	if (Ruid != Euid)
    666 		(void) setuid(Euid);
    667 
    668 	if (!created && aflag && prismember(&trace, SYS_execve)) {
    669 		psargs(pri);
    670 		Flush();
    671 	}
    672 
    673 	if (created && Pstate(Proc) != PS_STOP)	/* assertion */
    674 		if (!(interrupt | sigusr1))
    675 			abend("ASSERT error: process is not stopped", NULL);
    676 
    677 	traceeven = trace;		/* trace these system calls */
    678 
    679 	/* trace these regardless, even if we don't report results */
    680 	praddset(&traceeven, SYS_exit);
    681 	praddset(&traceeven, SYS_lwp_create);
    682 	praddset(&traceeven, SYS_lwp_exit);
    683 	praddset(&traceeven, SYS_exec);
    684 	praddset(&traceeven, SYS_execve);
    685 	praddset(&traceeven, SYS_open);
    686 	praddset(&traceeven, SYS_open64);
    687 	praddset(&traceeven, SYS_forkall);
    688 	praddset(&traceeven, SYS_vfork);
    689 	praddset(&traceeven, SYS_fork1);
    690 	praddset(&traceeven, SYS_forksys);
    691 
    692 	/* for I/O buffer dumps, force tracing of read()s and write()s */
    693 	if (!isemptyset(&readfd)) {
    694 		praddset(&traceeven, SYS_read);
    695 		praddset(&traceeven, SYS_readv);
    696 		praddset(&traceeven, SYS_pread);
    697 		praddset(&traceeven, SYS_pread64);
    698 		praddset(&traceeven, SYS_recv);
    699 		praddset(&traceeven, SYS_recvfrom);
    700 		praddset(&traceeven, SYS_recvmsg);
    701 	}
    702 	if (!isemptyset(&writefd)) {
    703 		praddset(&traceeven, SYS_write);
    704 		praddset(&traceeven, SYS_writev);
    705 		praddset(&traceeven, SYS_pwrite);
    706 		praddset(&traceeven, SYS_pwrite64);
    707 		praddset(&traceeven, SYS_send);
    708 		praddset(&traceeven, SYS_sendto);
    709 		praddset(&traceeven, SYS_sendmsg);
    710 	}
    711 
    712 	if (cflag || Eflag) {
    713 		Psetsysentry(Proc, &traceeven);
    714 	}
    715 	Psetsysexit(Proc, &traceeven);
    716 
    717 	/* special case -- cannot trace sysexit because context is changed */
    718 	if (prismember(&trace, SYS_context)) {
    719 		(void) Psysentry(Proc, SYS_context, TRUE);
    720 		(void) Psysexit(Proc, SYS_context, FALSE);
    721 		prdelset(&traceeven, SYS_context);
    722 	}
    723 
    724 	/* special case -- sysexit not traced by OS */
    725 	if (prismember(&trace, SYS_evtrapret)) {
    726 		(void) Psysentry(Proc, SYS_evtrapret, TRUE);
    727 		(void) Psysexit(Proc, SYS_evtrapret, FALSE);
    728 		prdelset(&traceeven, SYS_evtrapret);
    729 	}
    730 
    731 	/* special case -- trace exec() on entry to get the args */
    732 	(void) Psysentry(Proc, SYS_exec, TRUE);
    733 	(void) Psysentry(Proc, SYS_execve, TRUE);
    734 
    735 	/* special case -- sysexit never reached */
    736 	(void) Psysentry(Proc, SYS_exit, TRUE);
    737 	(void) Psysentry(Proc, SYS_lwp_exit, TRUE);
    738 	(void) Psysexit(Proc, SYS_exit, FALSE);
    739 	(void) Psysexit(Proc, SYS_lwp_exit, FALSE);
    740 
    741 	Psetsignal(Proc, &signals);	/* trace these signals */
    742 	Psetfault(Proc, &faults);	/* trace these faults */
    743 
    744 	/* for function call tracing */
    745 	if (Dynpat != NULL) {
    746 		/* trace these regardless, to deal with function calls */
    747 		(void) Pfault(Proc, FLTBPT, TRUE);
    748 		(void) Pfault(Proc, FLTTRACE, TRUE);
    749 
    750 		/* needed for x86 */
    751 		(void) Psetflags(Proc, PR_BPTADJ);
    752 
    753 		/*
    754 		 * Find functions and set breakpoints on grabbed process.
    755 		 * A process stopped on exec() gets its breakpoints set below.
    756 		 */
    757 		if ((Lsp->pr_why != PR_SYSENTRY &&
    758 		    Lsp->pr_why != PR_SYSEXIT) ||
    759 		    (Lsp->pr_what != SYS_exec &&
    760 		    Lsp->pr_what != SYS_execve)) {
    761 			establish_breakpoints();
    762 			establish_stacks();
    763 		}
    764 	}
    765 
    766 	/*
    767 	 * Use asynchronous-stop for multithreaded truss.
    768 	 * truss runs one lwp for each lwp in the target process.
    769 	 */
    770 	(void) Psetflags(Proc, PR_ASYNC);
    771 
    772 	/* flush out all tracing flags now. */
    773 	Psync(Proc);
    774 
    775 	/*
    776 	 * If we grabbed a running process, set it running again.
    777 	 * Since we are tracing lwp_create() and lwp_exit(), the
    778 	 * lwps will not change in the process until we create all
    779 	 * of the truss worker threads.
    780 	 * We leave a created process stopped so its exec() can be reported.
    781 	 */
    782 	first = created? FALSE : TRUE;
    783 	if (!created &&
    784 	    ((Pstate(Proc) == PS_STOP && Lsp->pr_why == PR_REQUESTED) ||
    785 	    (Lsp->pr_flags & PR_DSTOP)))
    786 		first = FALSE;
    787 
    788 	main_thread(first);
    789 	return (0);
    790 }
    791 
    792 /*
    793  * Called from main() and from control() after fork().
    794  */
    795 void
    796 main_thread(int first)
    797 {
    798 	private_t *pri = get_private();
    799 	struct tms tms;
    800 	int flags;
    801 	int retc;
    802 	int i;
    803 	int count;
    804 
    805 	/*
    806 	 * Block all signals in the main thread.
    807 	 * Some worker thread will receive signals.
    808 	 */
    809 	(void) thr_sigsetmask(SIG_SETMASK, &fillset, NULL);
    810 
    811 	/*
    812 	 * If we are dealing with a previously hung process,
    813 	 * arrange not to leave it hung on the same system call.
    814 	 */
    815 	primary_lwp = (first && Pstate(Proc) == PS_STOP)?
    816 		Pstatus(Proc)->pr_lwp.pr_lwpid : 0;
    817 
    818 	/*
    819 	 * Create worker threads to match the lwps in the target process.
    820 	 */
    821 	truss_nlwp = 0;
    822 	truss_maxlwp = 1;
    823 	truss_lwpid = my_realloc(truss_lwpid, sizeof (lwpid_t), NULL);
    824 	truss_lwpid[0] = 0;
    825 	count = 0;
    826 	(void) Plwp_iter(Proc, create_thread, &count);
    827 
    828 	if (count == 0) {
    829 		(void) printf("(Warning: no matching active LWPs found, "
    830 		    "waiting)\n");
    831 		Flush();
    832 	}
    833 
    834 	/*
    835 	 * Set all of the truss worker threads running now.
    836 	 */
    837 	(void) mutex_lock(&truss_lock);
    838 	for (i = 0; i < truss_maxlwp; i++) {
    839 		if (truss_lwpid[i])
    840 			(void) thr_continue(truss_lwpid[i]);
    841 	}
    842 	(void) mutex_unlock(&truss_lock);
    843 
    844 	/*
    845 	 * Wait until all worker threads terminate.
    846 	 */
    847 	while (thr_join(0, NULL, NULL) == 0)
    848 		continue;
    849 
    850 	(void) Punsetflags(Proc, PR_ASYNC);
    851 	Psync(Proc);
    852 	if (sigusr1)
    853 		letgo(pri);
    854 	flags = PRELEASE_CLEAR;
    855 	if (leave_hung)
    856 		flags |= PRELEASE_HANG;
    857 	Prelease(Proc, flags);
    858 
    859 	procdel();
    860 	retc = (leave_hung? 0 : wait4all());
    861 
    862 	if (!descendent) {
    863 		interrupt = 0;	/* another interrupt kills the report */
    864 		if (cflag) {
    865 			if (fflag)
    866 				file_to_parent();
    867 			report(pri, times(&tms) - starttime);
    868 		}
    869 	} else if (cflag && fflag) {
    870 		child_to_file();
    871 	}
    872 
    873 	exit(retc);	/* exit with exit status of created process, else 0 */
    874 }
    875 
    876 void *
    877 worker_thread(void *arg)
    878 {
    879 	struct ps_lwphandle *Lwp = (struct ps_lwphandle *)arg;
    880 	const pstatus_t *Psp = Pstatus(Proc);
    881 	const lwpstatus_t *Lsp = Lstatus(Lwp);
    882 	struct syscount *scp;
    883 	lwpid_t who = Lsp->pr_lwpid;
    884 	int first = (who == primary_lwp);
    885 	private_t *pri = get_private();
    886 	int req_flag = 0;
    887 	int leave_it_hung = FALSE;
    888 	int reset_traps = FALSE;
    889 	int gcode;
    890 	int what;
    891 	int ow_in_effect = 0;
    892 	long ow_syscall = 0;
    893 	long ow_subcode = 0;
    894 	char *ow_string = NULL;
    895 	sysset_t full_set;
    896 	sysset_t running_set;
    897 	int dotrace = lwptrace(Psp->pr_pid, Lsp->pr_lwpid);
    898 
    899 	pri->Lwp = Lwp;
    900 	pri->lwpstat = Lsp;
    901 	pri->syslast = Lsp->pr_stime;
    902 	pri->usrlast = Lsp->pr_utime;
    903 	make_pname(pri, 0);
    904 
    905 	prfillset(&full_set);
    906 
    907 	/* we were created with all signals blocked; unblock them */
    908 	(void) thr_sigsetmask(SIG_SETMASK, &emptyset, NULL);
    909 
    910 	/*
    911 	 * Run this loop until the victim lwp terminates or we receive
    912 	 * a termination condition (leave_hung | interrupt | sigusr1).
    913 	 */
    914 	for (;;) {
    915 		if (interrupt | sigusr1) {
    916 			(void) Lstop(Lwp, MILLISEC);
    917 			if (Lstate(Lwp) == PS_RUN)
    918 				break;
    919 		}
    920 		if (Lstate(Lwp) == PS_RUN) {
    921 			/* millisecond timeout is for sleeping syscalls */
    922 			uint_t tout = (iflag || req_flag)? 0 : MILLISEC;
    923 
    924 			/*
    925 			 * If we are to leave this lwp stopped in sympathy
    926 			 * with another lwp that has been left hung, or if
    927 			 * we have been interrupted or instructed to release
    928 			 * our victim process, and this lwp is stopped but
    929 			 * not on an event of interest to /proc, then just
    930 			 * leave it in that state.
    931 			 */
    932 			if ((leave_hung | interrupt | sigusr1) &&
    933 			    (Lsp->pr_flags & (PR_STOPPED|PR_ISTOP))
    934 			    == PR_STOPPED)
    935 				break;
    936 
    937 			(void) Lwait(Lwp, tout);
    938 			if (Lstate(Lwp) == PS_RUN &&
    939 			    tout != 0 && !(interrupt | sigusr1)) {
    940 				(void) mutex_lock(&truss_lock);
    941 				if ((Lsp->pr_flags & PR_STOPPED) &&
    942 				    Lsp->pr_why == PR_JOBCONTROL)
    943 					req_flag = jobcontrol(pri, dotrace);
    944 				else
    945 					req_flag = requested(pri, req_flag,
    946 					    dotrace);
    947 				(void) mutex_unlock(&truss_lock);
    948 			}
    949 			continue;
    950 		}
    951 		data_model = Psp->pr_dmodel;
    952 		if (Lstate(Lwp) == PS_UNDEAD)
    953 			break;
    954 		if (Lstate(Lwp) == PS_LOST) {	/* we lost control */
    955 			/*
    956 			 * After exec(), only one LWP remains in the process.
    957 			 * /proc makes the thread following that LWP receive
    958 			 * EAGAIN (PS_LOST) if the program being exec()ed
    959 			 * is a set-id program.  Every other controlling
    960 			 * thread receives ENOENT (because its LWP vanished).
    961 			 * We are the controlling thread for the exec()ing LWP.
    962 			 * We must wait until all of our siblings terminate
    963 			 * before attempting to reopen the process.
    964 			 */
    965 			(void) mutex_lock(&truss_lock);
    966 			while (truss_nlwp > 1)
    967 				(void) cond_wait(&truss_cv, &truss_lock);
    968 			if (Preopen(Proc) == 0) { /* we got control back */
    969 				/*
    970 				 * We have to free and re-grab the LWP.
    971 				 * The process is guaranteed to be at exit
    972 				 * from exec() or execve() and have only
    973 				 * one LWP, namely this one, and the LWP
    974 				 * is guaranteed to have lwpid == 1.
    975 				 * This "cannot fail".
    976 				 */
    977 				who = 1;
    978 				Lfree(Lwp);
    979 				pri->Lwp = Lwp =
    980 					Lgrab(Proc, who, &gcode);
    981 				if (Lwp == NULL)
    982 					abend("Lgrab error: ",
    983 						Lgrab_error(gcode));
    984 				pri->lwpstat = Lsp = Lstatus(Lwp);
    985 				(void) mutex_unlock(&truss_lock);
    986 				continue;
    987 			}
    988 
    989 			/* we really lost it */
    990 			if (pri->exec_string && *pri->exec_string) {
    991 				if (pri->exec_pname[0] != '\0')
    992 					(void) fputs(pri->exec_pname, stdout);
    993 				timestamp(pri);
    994 				(void) fputs(pri->exec_string, stdout);
    995 				(void) fputc('\n', stdout);
    996 			} else if (pri->length) {
    997 				(void) fputc('\n', stdout);
    998 			}
    999 			if (pri->sys_valid)
   1000 				(void) printf(
   1001 			"%s\t*** cannot trace across exec() of %s ***\n",
   1002 					pri->pname, pri->sys_path);
   1003 			else
   1004 				(void) printf(
   1005 				"%s\t*** lost control of process ***\n",
   1006 					pri->pname);
   1007 			pri->length = 0;
   1008 			Flush();
   1009 			(void) mutex_unlock(&truss_lock);
   1010 			break;
   1011 		}
   1012 		if (Lstate(Lwp) != PS_STOP) {
   1013 			(void) fprintf(stderr,
   1014 				"%s: state = %d\n", command, Lstate(Lwp));
   1015 			abend(pri->pname, "uncaught status of subject lwp");
   1016 		}
   1017 
   1018 		make_pname(pri, 0);
   1019 
   1020 		(void) mutex_lock(&truss_lock);
   1021 
   1022 		what = Lsp->pr_what;
   1023 		req_flag = 0;
   1024 
   1025 		switch (Lsp->pr_why) {
   1026 		case PR_REQUESTED:
   1027 			break;
   1028 		case PR_SIGNALLED:
   1029 			req_flag = signalled(pri, req_flag, dotrace);
   1030 			if (Sflag && !first && prismember(&sighang, what))
   1031 				leave_it_hung = TRUE;
   1032 			break;
   1033 		case PR_FAULTED:
   1034 			if (what == FLTBPT) {
   1035 				int rval;
   1036 
   1037 				(void) Pstop(Proc, 0);
   1038 				rval = function_trace(pri, first, 0, dotrace);
   1039 				if (rval == 1)
   1040 					leave_it_hung = TRUE;
   1041 				if (rval >= 0)
   1042 					break;
   1043 			}
   1044 			if (faulted(pri, dotrace) &&
   1045 			    Mflag && !first && prismember(&flthang, what))
   1046 				leave_it_hung = TRUE;
   1047 			break;
   1048 		case PR_JOBCONTROL:	/* can't happen except first time */
   1049 			req_flag = jobcontrol(pri, dotrace);
   1050 			break;
   1051 		case PR_SYSENTRY:
   1052 			/* protect ourself from operating system error */
   1053 			if (what <= 0 || what > PRMAXSYS)
   1054 				what = PRMAXSYS;
   1055 			pri->length = 0;
   1056 			/*
   1057 			 * ow_in_effect checks to see whether or not we
   1058 			 * are attempting to quantify the time spent in
   1059 			 * a one way system call.  This is necessary as
   1060 			 * some system calls never return, yet it is desireable
   1061 			 * to determine how much time the traced process
   1062 			 * spends in these calls.  To do this, a one way
   1063 			 * flag is set on SYSENTRY when the call is recieved.
   1064 			 * After this, the call mask for the SYSENTRY events
   1065 			 * is filled so that the traced process will stop
   1066 			 * on the entry to the very next system call.
   1067 			 * This appears to the the best way to determine
   1068 			 * system time elapsed between a one way system call.
   1069 			 * Once the next call occurs, values that have been
   1070 			 * stashed are used to record the correct syscall
   1071 			 * and time, and the SYSENTRY event mask is restored
   1072 			 * so that the traced process may continue.
   1073 			 */
   1074 			if (dotrace && ow_in_effect) {
   1075 				if (cflag) {
   1076 					(void) mutex_lock(&count_lock);
   1077 					scp = Cp->syscount[ow_syscall];
   1078 					if (ow_subcode != -1)
   1079 						scp += ow_subcode;
   1080 					scp->count++;
   1081 					accumulate(&scp->stime,
   1082 					    &Lsp->pr_stime, &pri->syslast);
   1083 					accumulate(&Cp->usrtotal,
   1084 					    &Lsp->pr_utime, &pri->usrlast);
   1085 					pri->syslast = Lsp->pr_stime;
   1086 					pri->usrlast = Lsp->pr_utime;
   1087 					(void) mutex_unlock(&count_lock);
   1088 				} else if (Eflag) {
   1089 					putpname(pri);
   1090 					timestamp(pri);
   1091 					(void) printf("%s\n", ow_string);
   1092 					free(ow_string);
   1093 					ow_string = NULL;
   1094 					pri->syslast = Lsp->pr_stime;
   1095 				}
   1096 				ow_in_effect = 0;
   1097 				Psetsysentry(Proc, &running_set);
   1098 			}
   1099 
   1100 			/*
   1101 			 * Special cases.  Most syscalls are traced on exit.
   1102 			 */
   1103 			switch (what) {
   1104 			case SYS_exit:			/* exit() */
   1105 			case SYS_lwp_exit:		/* lwp_exit() */
   1106 			case SYS_context:		/* [get|set]context() */
   1107 			case SYS_evtrapret:		/* evtrapret() */
   1108 				if (dotrace && cflag &&
   1109 				    prismember(&trace, what)) {
   1110 					ow_in_effect = 1;
   1111 					ow_syscall = what;
   1112 					ow_subcode = getsubcode(pri);
   1113 					pri->syslast = Lsp->pr_stime;
   1114 					running_set =
   1115 					    (Pstatus(Proc))->pr_sysentry;
   1116 					Psetsysentry(Proc, &full_set);
   1117 				} else if (dotrace && Eflag &&
   1118 				    prismember(&trace, what)) {
   1119 					(void) sysentry(pri, dotrace);
   1120 					ow_in_effect = 1;
   1121 					ow_string = my_malloc(
   1122 					    strlen(pri->sys_string) + 1, NULL);
   1123 					(void) strcpy(ow_string,
   1124 					    pri->sys_string);
   1125 					running_set =
   1126 					    (Pstatus(Proc))->pr_sysentry;
   1127 					Psetsysentry(Proc, &full_set);
   1128 					pri->syslast = Lsp->pr_stime;
   1129 				} else if (dotrace &&
   1130 				    prismember(&trace, what)) {
   1131 					(void) sysentry(pri, dotrace);
   1132 					putpname(pri);
   1133 					timestamp(pri);
   1134 					pri->length +=
   1135 						printf("%s\n", pri->sys_string);
   1136 					Flush();
   1137 				}
   1138 				pri->sys_leng = 0;
   1139 				*pri->sys_string = '\0';
   1140 
   1141 				if (what == SYS_exit)
   1142 					exit_called = TRUE;
   1143 				break;
   1144 			case SYS_exec:
   1145 			case SYS_execve:
   1146 				(void) sysentry(pri, dotrace);
   1147 				if (dotrace && !cflag &&
   1148 				    prismember(&trace, what)) {
   1149 					pri->exec_string =
   1150 						my_realloc(pri->exec_string,
   1151 						strlen(pri->sys_string) + 1,
   1152 						NULL);
   1153 					(void) strcpy(pri->exec_pname,
   1154 						pri->pname);
   1155 					(void) strcpy(pri->exec_string,
   1156 						pri->sys_string);
   1157 					pri->length += strlen(pri->sys_string);
   1158 					pri->exec_lwpid = Lsp->pr_lwpid;
   1159 				}
   1160 				pri->sys_leng = 0;
   1161 				*pri->sys_string = '\0';
   1162 				break;
   1163 			default:
   1164 				if (dotrace && (cflag || Eflag) &&
   1165 				    prismember(&trace, what)) {
   1166 					pri->syslast = Lsp->pr_stime;
   1167 				}
   1168 				break;
   1169 			}
   1170 			if (dotrace && Tflag && !first &&
   1171 			    (prismember(&syshang, what) ||
   1172 			    (exit_called && prismember(&syshang, SYS_exit))))
   1173 				leave_it_hung = TRUE;
   1174 			break;
   1175 		case PR_SYSEXIT:
   1176 			/* check for write open of a /proc file */
   1177 			if ((what == SYS_open || what == SYS_open64)) {
   1178 				(void) sysentry(pri, dotrace);
   1179 				pri->Errno = Lsp->pr_errno;
   1180 				pri->ErrPriv = Lsp->pr_errpriv;
   1181 				if ((pri->Errno == 0 || pri->Errno == EBUSY) &&
   1182 				    pri->sys_valid &&
   1183 				    (pri->sys_nargs > 1 &&
   1184 				    (pri->sys_args[1]&0x3) != O_RDONLY)) {
   1185 					int rv = checkproc(pri);
   1186 					if (rv == 1 && Fflag != PGRAB_FORCE) {
   1187 						/*
   1188 						 * The process opened itself
   1189 						 * and no -F flag was specified.
   1190 						 * Just print the open() call
   1191 						 * and let go of the process.
   1192 						 */
   1193 						if (dotrace && !cflag &&
   1194 						    prismember(&trace, what)) {
   1195 							putpname(pri);
   1196 							timestamp(pri);
   1197 							(void) printf("%s\n",
   1198 							    pri->sys_string);
   1199 							Flush();
   1200 						}
   1201 						sigusr1 = TRUE;
   1202 						(void) mutex_unlock(
   1203 							&truss_lock);
   1204 						goto out;
   1205 					}
   1206 					if (rv == 2) {
   1207 						/*
   1208 						 * Process opened someone else.
   1209 						 * The open is being reissued.
   1210 						 * Don't report this one.
   1211 						 */
   1212 						pri->sys_leng = 0;
   1213 						*pri->sys_string = '\0';
   1214 						pri->sys_nargs = 0;
   1215 						break;
   1216 					}
   1217 				}
   1218 			}
   1219 			if ((what == SYS_exec || what == SYS_execve) &&
   1220 			    pri->Errno == 0) {
   1221 				/*
   1222 				 * Refresh the data model on exec() in case it
   1223 				 * is different from the parent.  Lwait()
   1224 				 * doesn't update process-wide status, so we
   1225 				 * have to explicitly call Pstopstatus() to get
   1226 				 * the new state.
   1227 				 */
   1228 				(void) Pstopstatus(Proc, PCNULL, 0);
   1229 				data_model = Psp->pr_dmodel;
   1230 			}
   1231 			if (sysexit(pri, dotrace))
   1232 				Flush();
   1233 			if (what == SYS_lwp_create && pri->Rval1 != 0) {
   1234 				struct ps_lwphandle *new_Lwp;
   1235 				lwpid_t lwpid;
   1236 
   1237 				if ((new_Lwp = grab_lwp(pri->Rval1)) != NULL) {
   1238 					(void) thr_sigsetmask(SIG_SETMASK,
   1239 					    &fillset, NULL);
   1240 					if (thr_create(NULL, 0, worker_thread,
   1241 					    new_Lwp, THR_BOUND | THR_SUSPENDED,
   1242 					    &lwpid) != 0)
   1243 						abend("cannot create lwp ",
   1244 						    "to follow child lwp");
   1245 					insert_lwpid(lwpid);
   1246 					(void) thr_continue(lwpid);
   1247 					(void) thr_sigsetmask(SIG_SETMASK,
   1248 					    &emptyset, NULL);
   1249 				}
   1250 			}
   1251 			pri->sys_nargs = 0;
   1252 			if (dotrace && Tflag && !first &&
   1253 			    prismember(&syshang, what))
   1254 				leave_it_hung = TRUE;
   1255 			if ((what == SYS_exec || what == SYS_execve) &&
   1256 			    pri->Errno == 0) {
   1257 				is_vfork_child = FALSE;
   1258 				reset_breakpoints();
   1259 				/*
   1260 				 * exec() resets the calling LWP's lwpid to 1.
   1261 				 * If the LWP has changed its lwpid, then
   1262 				 * we have to free and re-grab the LWP
   1263 				 * in order to keep libproc consistent.
   1264 				 * This "cannot fail".
   1265 				 */
   1266 				if (who != Lsp->pr_lwpid) {
   1267 					/*
   1268 					 * We must wait for all of our
   1269 					 * siblings to terminate.
   1270 					 */
   1271 					while (truss_nlwp > 1)
   1272 						(void) cond_wait(&truss_cv,
   1273 							&truss_lock);
   1274 					who = Lsp->pr_lwpid;
   1275 					Lfree(Lwp);
   1276 					pri->Lwp = Lwp =
   1277 						Lgrab(Proc, who, &gcode);
   1278 					if (Lwp == NULL)
   1279 						abend("Lgrab error: ",
   1280 							Lgrab_error(gcode));
   1281 					pri->lwpstat = Lsp = Lstatus(Lwp);
   1282 				}
   1283 			}
   1284 			break;
   1285 		default:
   1286 			req_flag = 0;
   1287 			(void) fprintf(stderr,
   1288 				"unknown reason for stopping: %d/%d\n",
   1289 				Lsp->pr_why, what);
   1290 			abend(NULL, NULL);
   1291 		}
   1292 
   1293 		if (pri->child) {	/* controlled process fork()ed */
   1294 			if (fflag || Dynpat != NULL)  {
   1295 				if (Lsp->pr_why == PR_SYSEXIT &&
   1296 				    (Lsp->pr_what == SYS_vfork ||
   1297 				    (Lsp->pr_what == SYS_forksys &&
   1298 				    Lsp->pr_sysarg[0] == 2))) {
   1299 					is_vfork_child = TRUE;
   1300 					(void) Pstop(Proc, 0);
   1301 				}
   1302 				if (control(pri, pri->child)) {
   1303 					(void) mutex_unlock(&truss_lock);
   1304 					pri->child = 0;
   1305 					if (!fflag) {
   1306 						/*
   1307 						 * If this is vfork(), then
   1308 						 * this clears the breakpoints
   1309 						 * in the parent's address space
   1310 						 * as well as in the child's.
   1311 						 */
   1312 						clear_breakpoints();
   1313 						Prelease(Proc, PRELEASE_CLEAR);
   1314 						_exit(0);
   1315 					}
   1316 					main_thread(FALSE);
   1317 					/* NOTREACHED */
   1318 				}
   1319 
   1320 				/*
   1321 				 * Here, we are still the parent truss.
   1322 				 * If the child messes with the breakpoints and
   1323 				 * this is vfork(), we have to set them again.
   1324 				 */
   1325 				if (Dynpat != NULL && is_vfork_child && !fflag)
   1326 					reset_traps = TRUE;
   1327 				is_vfork_child = FALSE;
   1328 			}
   1329 			pri->child = 0;
   1330 		}
   1331 
   1332 		if (leave_it_hung) {
   1333 			(void) mutex_unlock(&truss_lock);
   1334 			break;
   1335 		}
   1336 
   1337 		if (reset_traps) {
   1338 			/*
   1339 			 * To recover from vfork, we must catch the lwp
   1340 			 * that issued the vfork() when it returns to user
   1341 			 * level, with all other lwps remaining stopped.
   1342 			 * For this purpose, we have directed all lwps to
   1343 			 * stop and we now set the vfork()ing lwp running
   1344 			 * with the PRSTEP flag.  We expect to capture it
   1345 			 * when it stops again showing PR_FAULTED/FLTTRACE.
   1346 			 * We are holding truss_lock, so no other threads
   1347 			 * in truss will set any other lwps in the victim
   1348 			 * process running.
   1349 			 */
   1350 			reset_traps = FALSE;
   1351 			(void) Lsetrun(Lwp, 0, PRSTEP);
   1352 			do {
   1353 				(void) Lwait(Lwp, 0);
   1354 			} while (Lstate(Lwp) == PS_RUN);
   1355 			if (Lstate(Lwp) == PS_STOP &&
   1356 			    Lsp->pr_why == PR_FAULTED &&
   1357 			    Lsp->pr_what == FLTTRACE) {
   1358 				reestablish_traps();
   1359 				(void) Lsetrun(Lwp, 0, PRCFAULT|PRSTOP);
   1360 			} else {
   1361 				(void) printf("%s\t*** Expected PR_FAULTED/"
   1362 					"FLTTRACE stop following vfork()\n",
   1363 					pri->pname);
   1364 			}
   1365 		}
   1366 
   1367 		if (Lstate(Lwp) == PS_STOP) {
   1368 			int flags = 0;
   1369 
   1370 			if (interrupt | sigusr1) {
   1371 				(void) mutex_unlock(&truss_lock);
   1372 				break;
   1373 			}
   1374 			/*
   1375 			 * If we must leave this lwp hung is sympathy with
   1376 			 * another lwp that is being left hung on purpose,
   1377 			 * then push the state onward toward PR_REQUESTED.
   1378 			 */
   1379 			if (leave_hung) {
   1380 				if (Lsp->pr_why == PR_REQUESTED) {
   1381 					(void) mutex_unlock(&truss_lock);
   1382 					break;
   1383 				}
   1384 				flags |= PRSTOP;
   1385 			}
   1386 			if (Lsetrun(Lwp, 0, flags) != 0 &&
   1387 			    Lstate(Lwp) != PS_LOST &&
   1388 			    Lstate(Lwp) != PS_UNDEAD) {
   1389 				(void) mutex_unlock(&truss_lock);
   1390 				perror("Lsetrun");
   1391 				abend("cannot start subject lwp", NULL);
   1392 				/* NOTREACHED */
   1393 			}
   1394 		}
   1395 		first = FALSE;
   1396 
   1397 		(void) mutex_unlock(&truss_lock);
   1398 	}
   1399 
   1400 out:
   1401 	/* block all signals in preparation for exiting */
   1402 	(void) thr_sigsetmask(SIG_SETMASK, &fillset, NULL);
   1403 
   1404 	if (Lstate(Lwp) == PS_UNDEAD || Lstate(Lwp) == PS_LOST)
   1405 		(void) mutex_lock(&truss_lock);
   1406 	else {
   1407 		(void) Lstop(Lwp, MILLISEC);
   1408 		(void) mutex_lock(&truss_lock);
   1409 		if (Lstate(Lwp) == PS_STOP &&
   1410 		    Lsp->pr_why == PR_FAULTED &&
   1411 		    Lsp->pr_what == FLTBPT)
   1412 			(void) function_trace(pri, 0, 1, dotrace);
   1413 	}
   1414 
   1415 	if (dotrace && ow_in_effect) {
   1416 		if (cflag) {
   1417 			(void) mutex_lock(&count_lock);
   1418 			scp = Cp->syscount[ow_syscall];
   1419 			if (ow_subcode != -1)
   1420 				scp += ow_subcode;
   1421 			scp->count++;
   1422 			accumulate(&scp->stime,
   1423 			    &Lsp->pr_stime, &pri->syslast);
   1424 			accumulate(&Cp->usrtotal,
   1425 			    &Lsp->pr_utime, &pri->usrlast);
   1426 			pri->syslast = Lsp->pr_stime;
   1427 			pri->usrlast = Lsp->pr_utime;
   1428 			(void) mutex_unlock(&count_lock);
   1429 		} else if (Eflag) {
   1430 			putpname(pri);
   1431 			timestamp(pri);
   1432 			(void) printf("%s\n", ow_string);
   1433 			free(ow_string);
   1434 			ow_string = NULL;
   1435 			pri->syslast = Lsp->pr_stime;
   1436 		}
   1437 		ow_in_effect = 0;
   1438 		Psetsysentry(Proc, &running_set);
   1439 	}
   1440 
   1441 	if (Lstate(Lwp) == PS_UNDEAD || Lstate(Lwp) == PS_LOST) {
   1442 		/*
   1443 		 * The victim thread has exited or we lost control of
   1444 		 * the process.  Remove ourself from the list of all
   1445 		 * truss threads and notify everyone waiting for this.
   1446 		 */
   1447 		lwpid_t my_id = thr_self();
   1448 		int i;
   1449 
   1450 		for (i = 0; i < truss_maxlwp; i++) {
   1451 			if (truss_lwpid[i] == my_id) {
   1452 				truss_lwpid[i] = 0;
   1453 				break;
   1454 			}
   1455 		}
   1456 		if (--truss_nlwp != 0) {
   1457 			(void) cond_broadcast(&truss_cv);
   1458 		} else {
   1459 			/*
   1460 			 * The last truss worker thread is terminating.
   1461 			 * The address space is gone (UNDEAD) or is
   1462 			 * inaccessible (LOST) so we cannot clear the
   1463 			 * breakpoints.  Just report the htable stats.
   1464 			 */
   1465 			report_htable_stats();
   1466 		}
   1467 	} else {
   1468 		/*
   1469 		 * The victim thread is not a zombie thread, and we have not
   1470 		 * lost control of the process.  We must have gotten here due
   1471 		 * to (leave_hung || leave_it_hung || interrupt || sigusr1).
   1472 		 * In these cases, we must carefully uninstrument the process
   1473 		 * and either set it running or leave it stopped and abandoned.
   1474 		 */
   1475 		static int nstopped = 0;
   1476 		static int cleared = 0;
   1477 
   1478 		if (leave_it_hung)
   1479 			leave_hung = TRUE;
   1480 		if ((leave_hung | interrupt | sigusr1) == 0)
   1481 			abend("(leave_hung | interrupt | sigusr1) == 0", NULL);
   1482 
   1483 		/*
   1484 		 * The first truss thread through here needs to instruct all
   1485 		 * application threads to stop -- they're not necessarily
   1486 		 * going to stop on their own.
   1487 		 */
   1488 		if (nstopped++ == 0)
   1489 			(void) Pdstop(Proc);
   1490 
   1491 		/*
   1492 		 * Notify all other worker threads about the reason
   1493 		 * for being here (leave_hung || interrupt || sigusr1).
   1494 		 */
   1495 		broadcast_signals();
   1496 
   1497 		/*
   1498 		 * Once the last thread has reached this point, then and
   1499 		 * only then is it safe to remove breakpoints and other
   1500 		 * instrumentation.  Since breakpoints are executed without
   1501 		 * truss_lock held, a monitor thread can't exit until all
   1502 		 * breakpoints have been removed, and we can't be sure the
   1503 		 * procedure to execute a breakpoint won't temporarily
   1504 		 * reinstall a breakpont.  Accordingly, we need to wait
   1505 		 * until all threads are in a known state.
   1506 		 */
   1507 		while (nstopped != truss_nlwp)
   1508 			(void) cond_wait(&truss_cv, &truss_lock);
   1509 
   1510 		/*
   1511 		 * All truss threads have reached this point.
   1512 		 * One of them clears the breakpoints and
   1513 		 * wakes up everybody else to finish up.
   1514 		 */
   1515 		if (cleared++ == 0) {
   1516 			/*
   1517 			 * All threads should already be stopped,
   1518 			 * but just to be safe...
   1519 			 */
   1520 			(void) Pstop(Proc, MILLISEC);
   1521 			clear_breakpoints();
   1522 			(void) Psysexit(Proc, SYS_forkall, FALSE);
   1523 			(void) Psysexit(Proc, SYS_vfork, FALSE);
   1524 			(void) Psysexit(Proc, SYS_fork1, FALSE);
   1525 			(void) Psysexit(Proc, SYS_forksys, FALSE);
   1526 			(void) Punsetflags(Proc, PR_FORK);
   1527 			Psync(Proc);
   1528 			fflag = 0;
   1529 			(void) cond_broadcast(&truss_cv);
   1530 		}
   1531 
   1532 		if (!leave_hung && Lstate(Lwp) == PS_STOP)
   1533 			(void) Lsetrun(Lwp, 0, 0);
   1534 	}
   1535 
   1536 	(void) Lfree(Lwp);
   1537 	(void) mutex_unlock(&truss_lock);
   1538 	return (NULL);
   1539 }
   1540 
   1541 /*
   1542  * Give a base date for time stamps, adjusted to the
   1543  * stop time of the selected (first or created) process.
   1544  */
   1545 void
   1546 setup_basetime(hrtime_t basehrtime, struct timeval *basedate)
   1547 {
   1548 	const pstatus_t *Psp = Pstatus(Proc);
   1549 	(void) mutex_lock(&count_lock);
   1550 	Cp->basetime = Psp->pr_lwp.pr_tstamp;
   1551 	(void) mutex_unlock(&count_lock);
   1552 
   1553 	if ((dflag|Dflag) && !cflag) {
   1554 		const struct tm *ptm;
   1555 		const char *ptime;
   1556 		const char *pdst;
   1557 		hrtime_t delta = basehrtime -
   1558 			((hrtime_t)Cp->basetime.tv_sec * NANOSEC +
   1559 			Cp->basetime.tv_nsec);
   1560 
   1561 		if (delta > 0) {
   1562 			basedate->tv_sec -= (time_t)(delta / NANOSEC);
   1563 			basedate->tv_usec -= (delta % NANOSEC) / 1000;
   1564 			if (basedate->tv_usec < 0) {
   1565 				basedate->tv_sec--;
   1566 				basedate->tv_usec += MICROSEC;
   1567 			}
   1568 		}
   1569 		ptm = localtime(&basedate->tv_sec);
   1570 		ptime = asctime(ptm);
   1571 		if ((pdst = tzname[ptm->tm_isdst ? 1 : 0]) == NULL)
   1572 			pdst = "???";
   1573 		if (dflag) {
   1574 			(void) printf(
   1575 			    "Base time stamp:  %ld.%4.4ld  [ %.20s%s %.4s ]\n",
   1576 			    basedate->tv_sec, basedate->tv_usec / 100,
   1577 			    ptime, pdst, ptime + 20);
   1578 			Flush();
   1579 		}
   1580 	}
   1581 }
   1582 
   1583 /*
   1584  * Performs per-process initializations. If truss is following a victim
   1585  * process it will fork additional truss processes to follow new processes
   1586  * created.  Here is where each new truss process gets its per-process data
   1587  * initialized.
   1588  */
   1589 
   1590 void
   1591 per_proc_init()
   1592 {
   1593 	void *pmem;
   1594 	struct timeval basedate;
   1595 	hrtime_t basehrtime;
   1596 	struct syscount *scp;
   1597 	int i;
   1598 	timestruc_t c_basetime;
   1599 
   1600 	/* Make sure we only configure the basetime for the first truss proc */
   1601 
   1602 	if (Cp == NULL) {
   1603 		pmem = my_malloc(sizeof (struct counts) + maxsyscalls() *
   1604 		    sizeof (struct syscount), NULL);
   1605 		Cp = (struct counts *)pmem;
   1606 		basehrtime = gethrtime();
   1607 		(void) gettimeofday(&basedate, NULL);
   1608 		setup_basetime(basehrtime, &basedate);
   1609 	}
   1610 
   1611 	c_basetime = Cp->basetime;
   1612 
   1613 	(void) memset(Cp, 0, sizeof (struct counts) + maxsyscalls() *
   1614 	    sizeof (struct syscount));
   1615 
   1616 	Cp->basetime = c_basetime;
   1617 
   1618 	if (fcall_tbl != NULL)
   1619 		destroy_hash(fcall_tbl);
   1620 	fcall_tbl = init_hash(4096);
   1621 
   1622 	(void) mutex_lock(&count_lock);
   1623 	scp = (struct syscount *)(Cp + 1);
   1624 	for (i = 0; i <= PRMAXSYS; i++) {
   1625 		Cp->syscount[i] = scp;
   1626 		scp += nsubcodes(i);
   1627 	}
   1628 	(void) mutex_unlock(&count_lock);
   1629 }
   1630 
   1631 
   1632 /*
   1633  * Writes child state to a tempfile where it can be read and
   1634  * accumulated by the parent process. The file descriptor is shared
   1635  * among the processes.  Ordering of writes does not matter, it is, however,
   1636  * necessary to ensure that all writes are atomic.
   1637  */
   1638 
   1639 void
   1640 child_to_file()
   1641 {
   1642 	hiter_t *itr;
   1643 	hentry_t *ntry;
   1644 	hdntry_t fentry;
   1645 	char *s = NULL;
   1646 	char *t = NULL;
   1647 	unsigned char *buf = NULL;
   1648 	size_t bufsz = 0;
   1649 	size_t i = 0;
   1650 	size_t j = 0;
   1651 
   1652 	/* ensure that we are in fact a child process */
   1653 	if (!descendent)
   1654 		return;
   1655 
   1656 	/* enumerate fcall_tbl (tbl locked until freed) */
   1657 	if (Dynpat != NULL) {
   1658 		itr = iterate_hash(fcall_tbl);
   1659 
   1660 		ntry = iter_next(itr);
   1661 		while (ntry != NULL) {
   1662 			fentry.type = HD_hashntry;
   1663 			fentry.count = ntry->count;
   1664 			s = ntry->key;
   1665 			t = ntry->lib;
   1666 			i = strlen(s) + 1;
   1667 			j = strlen(t) + 1;
   1668 			fentry.sz_key = i;
   1669 			fentry.sz_lib = j;
   1670 			if (i + sizeof (fentry) > bufsz) {
   1671 				buf = my_realloc(buf, i + j + sizeof (fentry),
   1672 				    NULL);
   1673 				bufsz = i + j + sizeof (fentry);
   1674 			}
   1675 			(void) memcpy(buf, &fentry, sizeof (fentry));
   1676 			(void) strlcpy((char *)(buf + sizeof (fentry)), t, j);
   1677 			(void) strlcpy((char *)(buf + sizeof (fentry) + j),
   1678 			    s, i);
   1679 			if (write(sfd, buf, sizeof (fentry) + i + j) == -1)
   1680 				abend("Error writing to tmp file", NULL);
   1681 			ntry = iter_next(itr);
   1682 		}
   1683 		iter_free(itr);
   1684 	}
   1685 
   1686 	/* Now write the count/syscount structs down */
   1687 	bufsz = sizeof (fentry) + (sizeof (struct counts) + maxsyscalls() *
   1688 	    sizeof (struct syscount));
   1689 	buf = my_realloc(buf, bufsz, NULL);
   1690 	fentry.type = HD_cts_syscts;
   1691 	fentry.count = 0;	/* undefined, really */
   1692 	fentry.sz_key = bufsz - sizeof (fentry);
   1693 	fentry.sz_lib = 0;	/* also undefined */
   1694 	(void) memcpy(buf, &fentry, sizeof (fentry));
   1695 	(void) memcpy((char *)(buf + sizeof (fentry)), Cp,
   1696 	    bufsz - sizeof (fentry));
   1697 	if (write(sfd, buf, bufsz) == -1)
   1698 		abend("Error writing cts/syscts to tmpfile", NULL);
   1699 
   1700 	free(buf);
   1701 }
   1702 
   1703 /*
   1704  * The following reads entries from the tempfile back to the parent
   1705  * so that information can be collected and summed for overall statistics.
   1706  * This reads records out of the tempfile.  If they are hash table entries,
   1707  * the record is merged with the hash table kept by the parent process.
   1708  * If the information is a struct count/struct syscount pair, they are
   1709  * copied and added into the count/syscount array kept by the parent.
   1710  */
   1711 
   1712 void
   1713 file_to_parent()
   1714 {
   1715 	hdntry_t ntry;
   1716 	char *s = NULL;
   1717 	char *t = NULL;
   1718 	size_t c_offset = 0;
   1719 	size_t filesz;
   1720 	size_t t_strsz = 0;
   1721 	size_t s_strsz = 0;
   1722 	struct stat fsi;
   1723 
   1724 	if (descendent)
   1725 		return;
   1726 
   1727 	if (fstat(sfd, &fsi) == -1)
   1728 		abend("Error stat-ing tempfile", NULL);
   1729 	filesz = fsi.st_size;
   1730 
   1731 	while (c_offset < filesz) {
   1732 		/* first get hdntry */
   1733 		if (pread(sfd, &ntry, sizeof (hdntry_t), c_offset) !=
   1734 		    sizeof (hdntry_t))
   1735 			abend("Unable to perform full read of hdntry", NULL);
   1736 		c_offset += sizeof (hdntry_t);
   1737 
   1738 		switch (ntry.type) {
   1739 		case HD_hashntry:
   1740 
   1741 			/* first get lib string */
   1742 			if (ntry.sz_lib > t_strsz) {
   1743 				t = my_realloc(t, ntry.sz_lib, NULL);
   1744 				t_strsz = ntry.sz_lib;
   1745 			}
   1746 
   1747 			(void) memset(t, 0, t_strsz);
   1748 
   1749 			/* now actually get the string */
   1750 			if (pread(sfd, t, ntry.sz_lib, c_offset) != ntry.sz_lib)
   1751 				abend("Unable to perform full read of lib str",
   1752 				    NULL);
   1753 			c_offset += ntry.sz_lib;
   1754 
   1755 			/* now get key string */
   1756 
   1757 			if (ntry.sz_key > s_strsz) {
   1758 				s = my_realloc(s, ntry.sz_key, NULL);
   1759 				s_strsz = ntry.sz_key;
   1760 			}
   1761 			(void) memset(s, 0, s_strsz);
   1762 			if (pread(sfd, s, ntry.sz_key, c_offset) != ntry.sz_key)
   1763 				abend("Unable to perform full read of key str",
   1764 				    NULL);
   1765 			c_offset += ntry.sz_key;
   1766 
   1767 			add_fcall(fcall_tbl, t, s, ntry.count);
   1768 			break;
   1769 
   1770 		case HD_cts_syscts:
   1771 		{
   1772 			struct counts *ncp;
   1773 			size_t bfsz = sizeof (struct counts) + maxsyscalls()
   1774 			    * sizeof (struct syscount);
   1775 			int i;
   1776 			struct syscount *sscp;
   1777 
   1778 			if (ntry.sz_key != bfsz)
   1779 				abend("cts/syscts size does not sanity check",
   1780 				    NULL);
   1781 			ncp = my_malloc(ntry.sz_key, NULL);
   1782 
   1783 			if (pread(sfd, ncp, ntry.sz_key, c_offset) !=
   1784 			    ntry.sz_key)
   1785 				abend("Unable to perform full read of cts",
   1786 				    NULL);
   1787 			c_offset += ntry.sz_key;
   1788 
   1789 			sscp = (struct syscount *)(ncp + 1);
   1790 
   1791 			(void) mutex_lock(&count_lock);
   1792 
   1793 			Cp->usrtotal.tv_sec += ncp->usrtotal.tv_sec;
   1794 			Cp->usrtotal.tv_nsec += ncp->usrtotal.tv_nsec;
   1795 			if (Cp->usrtotal.tv_nsec >= NANOSEC) {
   1796 				Cp->usrtotal.tv_nsec -= NANOSEC;
   1797 				Cp->usrtotal.tv_sec++;
   1798 			}
   1799 			for (i = 0; i <= PRMAXSYS; i++) {
   1800 				ncp->syscount[i] = sscp;
   1801 				sscp += nsubcodes(i);
   1802 			}
   1803 
   1804 			for (i = 0; i <= PRMAXFAULT; i++) {
   1805 				Cp->fltcount[i] += ncp->fltcount[i];
   1806 			}
   1807 
   1808 			for (i = 0; i <= PRMAXSIG; i++) {
   1809 				Cp->sigcount[i] += ncp->sigcount[i];
   1810 			}
   1811 
   1812 			for (i = 0; i <= PRMAXSYS; i++) {
   1813 				struct syscount *scp = Cp->syscount[i];
   1814 				struct syscount *nscp = ncp->syscount[i];
   1815 				int n = nsubcodes(i);
   1816 				int subcode;
   1817 
   1818 				for (subcode = 0; subcode < n; subcode++,
   1819 				    scp++, nscp++) {
   1820 					scp->count += nscp->count;
   1821 					scp->error += nscp->error;
   1822 					scp->stime.tv_sec += nscp->stime.tv_sec;
   1823 					scp->stime.tv_nsec +=
   1824 					    nscp->stime.tv_nsec;
   1825 					if (scp->stime.tv_nsec >= NANOSEC) {
   1826 						scp->stime.tv_nsec -= NANOSEC;
   1827 						scp->stime.tv_sec++;
   1828 					}
   1829 				}
   1830 			}
   1831 			(void) mutex_unlock(&count_lock);
   1832 			free(ncp);
   1833 			break;
   1834 		}
   1835 		default:
   1836 
   1837 			abend("Unknown file entry type encountered", NULL);
   1838 			break;
   1839 
   1840 		}
   1841 
   1842 		if (fstat(sfd, &fsi) == -1)
   1843 			abend("Error stat-ing tempfile", NULL);
   1844 		filesz = fsi.st_size;
   1845 	}
   1846 	if (s != NULL)
   1847 		free(s);
   1848 	if (t != NULL)
   1849 		free(t);
   1850 }
   1851 
   1852 void
   1853 make_pname(private_t *pri, id_t tid)
   1854 {
   1855 	if (!cflag) {
   1856 		int ff = (fflag || ngrab > 1);
   1857 		int lf = (lflag | tid | (Thr_agent != NULL) | (truss_nlwp > 1));
   1858 		pid_t pid = Pstatus(Proc)->pr_pid;
   1859 		id_t lwpid = pri->lwpstat->pr_lwpid;
   1860 
   1861 		if (ff != pri->pparam.ff ||
   1862 		    lf != pri->pparam.lf ||
   1863 		    pid != pri->pparam.pid ||
   1864 		    lwpid != pri->pparam.lwpid ||
   1865 		    tid != pri->pparam.tid) {
   1866 			char *s = pri->pname;
   1867 
   1868 			if (ff)
   1869 				s += sprintf(s, "%d", (int)pid);
   1870 			if (lf)
   1871 				s += sprintf(s, "/%d", (int)lwpid);
   1872 			if (tid)
   1873 				s += sprintf(s, "@%d", (int)tid);
   1874 			if (ff || lf)
   1875 				*s++ = ':', *s++ = '\t';
   1876 			if (ff && lf && s < pri->pname + 9)
   1877 				*s++ = '\t';
   1878 			*s = '\0';
   1879 			pri->pparam.ff = ff;
   1880 			pri->pparam.lf = lf;
   1881 			pri->pparam.pid = pid;
   1882 			pri->pparam.lwpid = lwpid;
   1883 			pri->pparam.tid = tid;
   1884 		}
   1885 	}
   1886 }
   1887 
   1888 /*
   1889  * Print the pri->pname[] string, if any.
   1890  */
   1891 void
   1892 putpname(private_t *pri)
   1893 {
   1894 	if (pri->pname[0])
   1895 		(void) fputs(pri->pname, stdout);
   1896 }
   1897 
   1898 /*
   1899  * Print the timestamp, if requested (-d, -D, or -E).
   1900  */
   1901 void
   1902 timestamp(private_t *pri)
   1903 {
   1904 	const lwpstatus_t *Lsp = pri->lwpstat;
   1905 	int seconds;
   1906 	int fraction;
   1907 
   1908 	if (!(dflag|Dflag|Eflag) || !(Lsp->pr_flags & PR_STOPPED))
   1909 		return;
   1910 
   1911 	seconds = Lsp->pr_tstamp.tv_sec - Cp->basetime.tv_sec;
   1912 	fraction = Lsp->pr_tstamp.tv_nsec - Cp->basetime.tv_nsec;
   1913 	if (fraction < 0) {
   1914 		seconds--;
   1915 		fraction += NANOSEC;
   1916 	}
   1917 	/* fraction in 1/10 milliseconds, rounded up */
   1918 	fraction = (fraction + 50000) / 100000;
   1919 	if (fraction >= (MILLISEC * 10)) {
   1920 		seconds++;
   1921 		fraction -= (MILLISEC * 10);
   1922 	}
   1923 
   1924 	if (dflag)		/* time stamp */
   1925 		(void) printf("%2d.%4.4d\t", seconds, fraction);
   1926 
   1927 	if (Dflag) {		/* time delta */
   1928 		int oseconds = pri->seconds;
   1929 		int ofraction = pri->fraction;
   1930 
   1931 		pri->seconds = seconds;
   1932 		pri->fraction = fraction;
   1933 		seconds -= oseconds;
   1934 		fraction -= ofraction;
   1935 		if (fraction < 0) {
   1936 			seconds--;
   1937 			fraction += (MILLISEC * 10);
   1938 		}
   1939 		(void) printf("%2d.%4.4d\t", seconds, fraction);
   1940 	}
   1941 
   1942 	if (Eflag) {
   1943 		seconds = Lsp->pr_stime.tv_sec - pri->syslast.tv_sec;
   1944 		fraction = Lsp->pr_stime.tv_nsec - pri->syslast.tv_nsec;
   1945 
   1946 		if (fraction < 0) {
   1947 			seconds--;
   1948 			fraction += NANOSEC;
   1949 		}
   1950 		/* fraction in 1/10 milliseconds, rounded up */
   1951 		fraction = (fraction + 50000) / 100000;
   1952 		if (fraction >= (MILLISEC * 10)) {
   1953 			seconds++;
   1954 			fraction -= (MILLISEC * 10);
   1955 		}
   1956 		(void) printf("%2d.%4.4d\t", seconds, fraction);
   1957 	}
   1958 }
   1959 
   1960 /*
   1961  * Create output file, being careful about
   1962  * suid/sgid and file descriptor 0, 1, 2 issues.
   1963  */
   1964 int
   1965 xcreat(char *path)
   1966 {
   1967 	int fd;
   1968 	int mode = 0666;
   1969 
   1970 	if (Euid == Ruid && Egid == Rgid)	/* not set-id */
   1971 		fd = creat(path, mode);
   1972 	else if (access(path, F_OK) != 0) {	/* file doesn't exist */
   1973 		/* if directory permissions OK, create file & set ownership */
   1974 
   1975 		char *dir;
   1976 		char *p;
   1977 		char dot[4];
   1978 
   1979 		/* generate path for directory containing file */
   1980 		if ((p = strrchr(path, '/')) == NULL) {	/* no '/' */
   1981 			p = dir = dot;
   1982 			*p++ = '.';		/* current directory */
   1983 			*p = '\0';
   1984 		} else if (p == path) {			/* leading '/' */
   1985 			p = dir = dot;
   1986 			*p++ = '/';		/* root directory */
   1987 			*p = '\0';
   1988 		} else {				/* embedded '/' */
   1989 			dir = path;		/* directory path */
   1990 			*p = '\0';
   1991 		}
   1992 
   1993 		if (access(dir, W_OK|X_OK) != 0) {
   1994 			/* not writeable/searchable */
   1995 			*p = '/';
   1996 			fd = -1;
   1997 		} else {	/* create file and set ownership correctly */
   1998 			*p = '/';
   1999 			if ((fd = creat(path, mode)) >= 0)
   2000 				(void) chown(path, (int)Ruid, (int)Rgid);
   2001 		}
   2002 	} else if (access(path, W_OK) != 0)	/* file not writeable */
   2003 		fd = -1;
   2004 	else
   2005 		fd = creat(path, mode);
   2006 
   2007 	/*
   2008 	 * Make sure it's not one of 0, 1, or 2.
   2009 	 * This allows truss to work when spawned by init(1m).
   2010 	 */
   2011 	if (0 <= fd && fd <= 2) {
   2012 		int dfd = fcntl(fd, F_DUPFD, 3);
   2013 		(void) close(fd);
   2014 		fd = dfd;
   2015 	}
   2016 
   2017 	/*
   2018 	 * Mark it close-on-exec so created processes don't inherit it.
   2019 	 */
   2020 	if (fd >= 0)
   2021 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
   2022 
   2023 	return (fd);
   2024 }
   2025 
   2026 void
   2027 setoutput(int ofd)
   2028 {
   2029 	if (ofd < 0) {
   2030 		(void) close(1);
   2031 		(void) fcntl(2, F_DUPFD, 1);
   2032 	} else if (ofd != 1) {
   2033 		(void) close(1);
   2034 		(void) fcntl(ofd, F_DUPFD, 1);
   2035 		(void) close(ofd);
   2036 		/* if no stderr, make it the same file */
   2037 		if ((ofd = dup(2)) < 0)
   2038 			(void) fcntl(1, F_DUPFD, 2);
   2039 		else
   2040 			(void) close(ofd);
   2041 	}
   2042 }
   2043 
   2044 /*
   2045  * Accumulate time differencies:  a += e - s;
   2046  */
   2047 void
   2048 accumulate(timestruc_t *ap, const timestruc_t *ep, const timestruc_t *sp)
   2049 {
   2050 	ap->tv_sec += ep->tv_sec - sp->tv_sec;
   2051 	ap->tv_nsec += ep->tv_nsec - sp->tv_nsec;
   2052 	if (ap->tv_nsec >= NANOSEC) {
   2053 		ap->tv_nsec -= NANOSEC;
   2054 		ap->tv_sec++;
   2055 	} else if (ap->tv_nsec < 0) {
   2056 		ap->tv_nsec += NANOSEC;
   2057 		ap->tv_sec--;
   2058 	}
   2059 }
   2060 
   2061 int
   2062 lib_sort(const void *p1, const void *p2)
   2063 {
   2064 	int cmpr = 0;
   2065 	long i;
   2066 	long j;
   2067 
   2068 	hentry_t *t1 = (hentry_t *)p1;
   2069 	hentry_t *t2 = (hentry_t *)p2;
   2070 
   2071 	char *p = t1->lib;
   2072 	char *q = t2->lib;
   2073 
   2074 	if ((cmpr = strcmp(p, q)) == 0) {
   2075 		i = t1->count;
   2076 		j = t2->count;
   2077 		if (i > j)
   2078 			return (-1);
   2079 		else if (i < j)
   2080 			return (1);
   2081 		else {
   2082 			p = t1->key;
   2083 			q = t2->key;
   2084 			return (strcmp(p, q));
   2085 		}
   2086 	} else
   2087 		return (cmpr);
   2088 }
   2089 
   2090 void
   2091 report(private_t *pri, time_t lapse)	/* elapsed time, clock ticks */
   2092 {
   2093 	int i;
   2094 	long count;
   2095 	const char *name;
   2096 	long error;
   2097 	long total;
   2098 	long errtot;
   2099 	timestruc_t tickzero;
   2100 	timestruc_t ticks;
   2101 	timestruc_t ticktot;
   2102 
   2103 	if (descendent)
   2104 		return;
   2105 
   2106 	for (i = 0, total = 0; i <= PRMAXFAULT && !interrupt; i++) {
   2107 		if ((count = Cp->fltcount[i]) != 0) {
   2108 			if (total == 0)		/* produce header */
   2109 				(void) printf("faults -------------\n");
   2110 
   2111 			name = proc_fltname(i, pri->flt_name,
   2112 				sizeof (pri->flt_name));
   2113 
   2114 			(void) printf("%s%s\t%4ld\n", name,
   2115 				(((int)strlen(name) < 8)?
   2116 				    (const char *)"\t" : (const char *)""),
   2117 				count);
   2118 			total += count;
   2119 		}
   2120 	}
   2121 	if (total && !interrupt)
   2122 		(void) printf("total:\t\t%4ld\n\n", total);
   2123 
   2124 	for (i = 0, total = 0; i <= PRMAXSIG && !interrupt; i++) {
   2125 		if ((count = Cp->sigcount[i]) != 0) {
   2126 			if (total == 0)		/* produce header */
   2127 				(void) printf("signals ------------\n");
   2128 			name = signame(pri, i);
   2129 			(void) printf("%s%s\t%4ld\n", name,
   2130 				(((int)strlen(name) < 8)?
   2131 				    (const char *)"\t" : (const char *)""),
   2132 				count);
   2133 			total += count;
   2134 		}
   2135 	}
   2136 	if (total && !interrupt)
   2137 		(void) printf("total:\t\t%4ld\n\n", total);
   2138 
   2139 	if ((Dynpat != NULL) && !interrupt) {
   2140 		size_t elem = elements_in_table(fcall_tbl);
   2141 		hiter_t *itr = iterate_hash(fcall_tbl);
   2142 		hentry_t *tmp = iter_next(itr);
   2143 		hentry_t *stbl = my_malloc(elem * sizeof (hentry_t), NULL);
   2144 		i = 0;
   2145 		while ((tmp != NULL) && (i < elem)) {
   2146 			stbl[i].prev = tmp->prev;
   2147 			stbl[i].next = tmp->next;
   2148 			stbl[i].lib = tmp->lib;
   2149 			stbl[i].key = tmp->key;
   2150 			stbl[i].count = tmp->count;
   2151 			tmp = iter_next(itr);
   2152 			i++;
   2153 		}
   2154 		qsort((void *)stbl, elem, sizeof (hentry_t),
   2155 		    lib_sort);
   2156 		(void) printf(
   2157 			"\n%-20s %-40s %s\n", "Library:", "Function", "calls");
   2158 		for (i = 0; i < elem; i++) {
   2159 			(void) printf("%-20s %-40s %ld\n", stbl[i].lib,
   2160 			    stbl[i].key, stbl[i].count);
   2161 		}
   2162 		iter_free(itr);
   2163 		free(stbl);
   2164 		itr = NULL;
   2165 	}
   2166 
   2167 	if (!interrupt)
   2168 		(void) printf(
   2169 		"\nsyscall               seconds   calls  errors\n");
   2170 
   2171 	total = errtot = 0;
   2172 	tickzero.tv_sec = ticks.tv_sec = ticktot.tv_sec = 0;
   2173 	tickzero.tv_nsec = ticks.tv_nsec = ticktot.tv_nsec = 0;
   2174 	for (i = 0; i <= PRMAXSYS && !interrupt; i++) {
   2175 		struct syscount *scp = Cp->syscount[i];
   2176 		int n = nsubcodes(i);
   2177 		int subcode;
   2178 
   2179 		for (subcode = 0; subcode < n; subcode++, scp++) {
   2180 			if ((count = scp->count) != 0 || scp->error) {
   2181 				(void) printf("%-19.19s ",
   2182 					sysname(pri, i, subcode));
   2183 
   2184 				ticks = scp->stime;
   2185 				accumulate(&ticktot, &ticks, &tickzero);
   2186 				prtim(&ticks);
   2187 
   2188 				(void) printf(" %7ld", count);
   2189 				if ((error = scp->error) != 0)
   2190 					(void) printf(" %7ld", error);
   2191 				(void) fputc('\n', stdout);
   2192 				total += count;
   2193 				errtot += error;
   2194 			}
   2195 		}
   2196 	}
   2197 
   2198 	if (!interrupt) {
   2199 		(void) printf(
   2200 		"                     --------  ------   ----\n");
   2201 		(void) printf("sys totals:         ");
   2202 		prtim(&ticktot);
   2203 		(void) printf(" %7ld %6ld\n", total, errtot);
   2204 	}
   2205 
   2206 	if (!interrupt) {
   2207 		(void) printf("usr time:           ");
   2208 		prtim(&Cp->usrtotal);
   2209 		(void) fputc('\n', stdout);
   2210 	}
   2211 
   2212 	if (!interrupt) {
   2213 		int hz = (int)sysconf(_SC_CLK_TCK);
   2214 
   2215 		ticks.tv_sec = lapse / hz;
   2216 		ticks.tv_nsec = (lapse % hz) * (1000000000 / hz);
   2217 		(void) printf("elapsed:            ");
   2218 		prtim(&ticks);
   2219 		(void) fputc('\n', stdout);
   2220 	}
   2221 }
   2222 
   2223 void
   2224 prtim(timestruc_t *tp)
   2225 {
   2226 	time_t sec;
   2227 
   2228 	if ((sec = tp->tv_sec) != 0)			/* whole seconds */
   2229 		(void) printf("%5lu", sec);
   2230 	else
   2231 		(void) printf("     ");
   2232 
   2233 	(void) printf(".%3.3ld", tp->tv_nsec/1000000);	/* fraction */
   2234 }
   2235 
   2236 /*
   2237  * Gather process id's.
   2238  * Return 0 on success, != 0 on failure.
   2239  */
   2240 void
   2241 pids(char *arg, proc_set_t *grab)
   2242 {
   2243 	pid_t pid = -1;
   2244 	int i;
   2245 	const char *lwps = NULL;
   2246 
   2247 	if ((pid = proc_arg_xpsinfo(arg, PR_ARG_PIDS, NULL, &i, &lwps)) < 0) {
   2248 		(void) fprintf(stderr, "%s: cannot trace '%s': %s\n",
   2249 		    command, arg, Pgrab_error(i));
   2250 		return;
   2251 	}
   2252 
   2253 	for (i = 0; i < ngrab; i++)
   2254 		if (grab[i].pid == pid)	/* duplicate */
   2255 			break;
   2256 
   2257 	if (i == ngrab) {
   2258 		grab[ngrab].pid = pid;
   2259 		grab[ngrab].lwps = lwps;
   2260 		ngrab++;
   2261 	} else {
   2262 		(void) fprintf(stderr, "%s: duplicate process-id ignored: %d\n",
   2263 		    command, (int)pid);
   2264 	}
   2265 }
   2266 
   2267 /*
   2268  * Report psargs string.
   2269  */
   2270 void
   2271 psargs(private_t *pri)
   2272 {
   2273 	pid_t pid = Pstatus(Proc)->pr_pid;
   2274 	psinfo_t psinfo;
   2275 
   2276 	if (proc_get_psinfo(pid, &psinfo) == 0)
   2277 		(void) printf("%spsargs: %.64s\n",
   2278 			pri->pname, psinfo.pr_psargs);
   2279 	else {
   2280 		perror("psargs()");
   2281 		(void) printf("%s\t*** Cannot read psinfo file for pid %d\n",
   2282 			pri->pname, (int)pid);
   2283 	}
   2284 }
   2285 
   2286 char *
   2287 fetchstring(private_t *pri, long addr, int maxleng)
   2288 {
   2289 	int nbyte;
   2290 	int leng = 0;
   2291 	char string[41];
   2292 
   2293 	string[40] = '\0';
   2294 	if (pri->str_bsize == 0)  /* initial allocation of string buffer */
   2295 		pri->str_buffer =
   2296 			my_malloc(pri->str_bsize = 16, "string buffer");
   2297 	*pri->str_buffer = '\0';
   2298 
   2299 	for (nbyte = 40; nbyte == 40 && leng < maxleng; addr += 40) {
   2300 		if ((nbyte = Pread(Proc, string, 40, addr)) <= 0)
   2301 			return (leng? pri->str_buffer : NULL);
   2302 		if (nbyte > 0 &&
   2303 		    (nbyte = strlen(string)) > 0) {
   2304 			while (leng + nbyte >= pri->str_bsize)
   2305 				pri->str_buffer =
   2306 					my_realloc(pri->str_buffer,
   2307 					pri->str_bsize *= 2, "string buffer");
   2308 			(void) strcpy(pri->str_buffer+leng, string);
   2309 			leng += nbyte;
   2310 		}
   2311 	}
   2312 
   2313 	if (leng > maxleng)
   2314 		leng = maxleng;
   2315 	pri->str_buffer[leng] = '\0';
   2316 
   2317 	return (pri->str_buffer);
   2318 }
   2319 
   2320 void
   2321 show_cred(private_t *pri, int new)
   2322 {
   2323 	prcred_t cred;
   2324 
   2325 	if (proc_get_cred(Pstatus(Proc)->pr_pid, &cred, 0) < 0) {
   2326 		perror("show_cred()");
   2327 		(void) printf("%s\t*** Cannot get credentials\n", pri->pname);
   2328 		return;
   2329 	}
   2330 
   2331 	if (!cflag && prismember(&trace, SYS_exec)) {
   2332 		if (new)
   2333 			credentials = cred;
   2334 		if ((new && cred.pr_ruid != cred.pr_suid) ||
   2335 		    cred.pr_ruid != credentials.pr_ruid ||
   2336 		    cred.pr_suid != credentials.pr_suid)
   2337 			(void) printf(
   2338 		"%s    *** SUID: ruid/euid/suid = %d / %d / %d  ***\n",
   2339 			pri->pname,
   2340 			(int)cred.pr_ruid,
   2341 			(int)cred.pr_euid,
   2342 			(int)cred.pr_suid);
   2343 		if ((new && cred.pr_rgid != cred.pr_sgid) ||
   2344 		    cred.pr_rgid != credentials.pr_rgid ||
   2345 		    cred.pr_sgid != credentials.pr_sgid)
   2346 			(void) printf(
   2347 		"%s    *** SGID: rgid/egid/sgid = %d / %d / %d  ***\n",
   2348 			pri->pname,
   2349 			(int)cred.pr_rgid,
   2350 			(int)cred.pr_egid,
   2351 			(int)cred.pr_sgid);
   2352 	}
   2353 
   2354 	credentials = cred;
   2355 }
   2356 
   2357 /*
   2358  * Take control of a child process.
   2359  * We come here with truss_lock held.
   2360  */
   2361 int
   2362 control(private_t *pri, pid_t pid)
   2363 {
   2364 	const pstatus_t *Psp;
   2365 	const lwpstatus_t *Lsp;
   2366 	pid_t childpid = 0;
   2367 	long flags;
   2368 	int rc;
   2369 
   2370 	(void) mutex_lock(&gps->fork_lock);
   2371 	while (gps->fork_pid != 0)
   2372 		(void) cond_wait(&gps->fork_cv, &gps->fork_lock);
   2373 	gps->fork_pid = getpid();	/* parent pid */
   2374 	if ((childpid = fork()) == -1) {
   2375 		(void) printf("%s\t*** Cannot fork() to control process #%d\n",
   2376 			pri->pname, (int)pid);
   2377 		Flush();
   2378 		gps->fork_pid = 0;
   2379 		(void) cond_broadcast(&gps->fork_cv);
   2380 		(void) mutex_unlock(&gps->fork_lock);
   2381 		release(pri, pid);
   2382 		return (FALSE);
   2383 	}
   2384 
   2385 	if (childpid != 0) {
   2386 		/*
   2387 		 * The parent carries on, after a brief pause.
   2388 		 * The parent must wait until the child executes procadd(pid).
   2389 		 */
   2390 		while (gps->fork_pid != childpid)
   2391 			(void) cond_wait(&gps->fork_cv, &gps->fork_lock);
   2392 		gps->fork_pid = 0;
   2393 		(void) cond_broadcast(&gps->fork_cv);
   2394 		(void) mutex_unlock(&gps->fork_lock);
   2395 		return (FALSE);
   2396 	}
   2397 
   2398 	childpid = getpid();
   2399 	descendent = TRUE;
   2400 	exit_called = FALSE;
   2401 	Pfree(Proc);	/* forget old process */
   2402 
   2403 	/*
   2404 	 * The parent process owns the shared gps->fork_lock.
   2405 	 * The child must grab it again.
   2406 	 */
   2407 	(void) mutex_lock(&gps->fork_lock);
   2408 
   2409 	/*
   2410 	 * Child grabs the process and retains the tracing flags.
   2411 	 */
   2412 	if ((Proc = Pgrab(pid, PGRAB_RETAIN, &rc)) == NULL) {
   2413 		(void) fprintf(stderr,
   2414 			"%s: cannot control child process, pid# %d: %s\n",
   2415 			command, (int)pid, Pgrab_error(rc));
   2416 		gps->fork_pid = childpid;
   2417 		(void) cond_broadcast(&gps->fork_cv);
   2418 		(void) mutex_unlock(&gps->fork_lock);
   2419 		exit(2);
   2420 	}
   2421 
   2422 	per_proc_init();
   2423 	/*
   2424 	 * Add ourself to the set of truss processes
   2425 	 * and notify the parent to carry on.
   2426 	 */
   2427 	procadd(pid, NULL);
   2428 	gps->fork_pid = childpid;
   2429 	(void) cond_broadcast(&gps->fork_cv);
   2430 	(void) mutex_unlock(&gps->fork_lock);
   2431 
   2432 	/*
   2433 	 * We may have grabbed the child before it is fully stopped on exit
   2434 	 * from fork.  Wait one second (at most) for it to settle down.
   2435 	 */
   2436 	(void) Pwait(Proc, MILLISEC);
   2437 	if (Rdb_agent != NULL)
   2438 		Rdb_agent = Prd_agent(Proc);
   2439 
   2440 	Psp = Pstatus(Proc);
   2441 	Lsp = &Psp->pr_lwp;
   2442 	pri->lwpstat = Lsp;
   2443 	data_model = Psp->pr_dmodel;
   2444 
   2445 	make_pname(pri, 0);
   2446 
   2447 	pri->syslast = Psp->pr_stime;
   2448 	pri->usrlast = Psp->pr_utime;
   2449 
   2450 	flags = PR_FORK | PR_ASYNC;
   2451 	if (Dynpat != NULL)
   2452 		flags |= PR_BPTADJ;	/* needed for x86 */
   2453 	(void) Psetflags(Proc, flags);
   2454 
   2455 	return (TRUE);
   2456 }
   2457 
   2458 /*
   2459  * Take control of an existing process.
   2460  */
   2461 int
   2462 grabit(private_t *pri, proc_set_t *set)
   2463 {
   2464 	const pstatus_t *Psp;
   2465 	const lwpstatus_t *Lsp;
   2466 	int gcode;
   2467 
   2468 	/*
   2469 	 * Don't force the takeover unless the -F option was specified.
   2470 	 */
   2471 	if ((Proc = Pgrab(set->pid, Fflag, &gcode)) == NULL) {
   2472 		(void) fprintf(stderr, "%s: %s: %d\n",
   2473 			command, Pgrab_error(gcode), (int)set->pid);
   2474 		pri->lwpstat = NULL;
   2475 		return (FALSE);
   2476 	}
   2477 	Psp = Pstatus(Proc);
   2478 	Lsp = &Psp->pr_lwp;
   2479 	pri->lwpstat = Lsp;
   2480 
   2481 	make_pname(pri, 0);
   2482 
   2483 	data_model = Psp->pr_dmodel;
   2484 	pri->syslast = Psp->pr_stime;
   2485 	pri->usrlast = Psp->pr_utime;
   2486 
   2487 	if (fflag || Dynpat != NULL)
   2488 		(void) Psetflags(Proc, PR_FORK);
   2489 	else
   2490 		(void) Punsetflags(Proc, PR_FORK);
   2491 	procadd(set->pid, set->lwps);
   2492 	show_cred(pri, TRUE);
   2493 	return (TRUE);
   2494 }
   2495 
   2496 /*
   2497  * Release process from control.
   2498  */
   2499 void
   2500 release(private_t *pri, pid_t pid)
   2501 {
   2502 	/*
   2503 	 * The process in question is the child of a traced process.
   2504 	 * We are here to turn off the inherited tracing flags.
   2505 	 */
   2506 	int fd;
   2507 	char ctlname[100];
   2508 	long ctl[2];
   2509 
   2510 	ctl[0] = PCSET;
   2511 	ctl[1] = PR_RLC;
   2512 
   2513 	/* process is freshly forked, no need for exclusive open */
   2514 	(void) sprintf(ctlname, "/proc/%d/ctl", (int)pid);
   2515 	if ((fd = open(ctlname, O_WRONLY)) < 0 ||
   2516 	    write(fd, (char *)ctl, sizeof (ctl)) < 0) {
   2517 		perror("release()");
   2518 		(void) printf(
   2519 			"%s\t*** Cannot release child process, pid# %d\n",
   2520 			pri->pname, (int)pid);
   2521 		Flush();
   2522 	}
   2523 	if (fd >= 0)	/* run-on-last-close sets the process running */
   2524 		(void) close(fd);
   2525 }
   2526 
   2527 void
   2528 intr(int sig)
   2529 {
   2530 	/*
   2531 	 * SIGUSR1 is special.  It is used by one truss process to tell
   2532 	 * another truss process to release its controlled process.
   2533 	 * SIGUSR2 is also special.  It is used to wake up threads waiting
   2534 	 * for a victim lwp to stop after an event that will leave the
   2535 	 * process hung (stopped and abandoned) has occurred.
   2536 	 */
   2537 	if (sig == SIGUSR1) {
   2538 		sigusr1 = TRUE;
   2539 	} else if (sig == SIGUSR2) {
   2540 		void *value;
   2541 		private_t *pri;
   2542 		struct ps_lwphandle *Lwp;
   2543 
   2544 		if (thr_getspecific(private_key, &value) == 0 &&
   2545 		    (pri = value) != NULL &&
   2546 		    (Lwp = pri->Lwp) != NULL)
   2547 			(void) Lstop(Lwp, MILLISEC / 10);
   2548 	} else {
   2549 		interrupt = sig;
   2550 	}
   2551 }
   2552 
   2553 void
   2554 errmsg(const char *s, const char *q)
   2555 {
   2556 	char msg[512];
   2557 
   2558 	if (s || q) {
   2559 		msg[0] = '\0';
   2560 		if (command) {
   2561 			(void) strcpy(msg, command);
   2562 			(void) strcat(msg, ": ");
   2563 		}
   2564 		if (s)
   2565 			(void) strcat(msg, s);
   2566 		if (q)
   2567 			(void) strcat(msg, q);
   2568 		(void) strcat(msg, "\n");
   2569 		(void) write(2, msg, (size_t)strlen(msg));
   2570 	}
   2571 }
   2572 
   2573 void
   2574 abend(const char *s, const char *q)
   2575 {
   2576 	(void) thr_sigsetmask(SIG_SETMASK, &fillset, NULL);
   2577 	if (Proc) {
   2578 		Flush();
   2579 		errmsg(s, q);
   2580 		clear_breakpoints();
   2581 		(void) Punsetflags(Proc, PR_ASYNC);
   2582 		Prelease(Proc, created? PRELEASE_KILL : PRELEASE_CLEAR);
   2583 		procdel();
   2584 		(void) wait4all();
   2585 	} else {
   2586 		errmsg(s, q);
   2587 	}
   2588 	exit(2);
   2589 }
   2590 
   2591 /*
   2592  * Allocate memory.
   2593  * If allocation fails then print a message and abort.
   2594  */
   2595 void *
   2596 my_realloc(void *buf, size_t size, const char *msg)
   2597 {
   2598 	if ((buf = realloc(buf, size)) == NULL) {
   2599 		if (msg != NULL)
   2600 			abend("cannot allocate ", msg);
   2601 		else
   2602 			abend("memory allocation failure", NULL);
   2603 	}
   2604 
   2605 	return (buf);
   2606 }
   2607 
   2608 void *
   2609 my_calloc(size_t nelem, size_t elsize, const char *msg)
   2610 {
   2611 	void *buf = NULL;
   2612 
   2613 	if ((buf = calloc(nelem, elsize)) == NULL) {
   2614 		if (msg != NULL)
   2615 			abend("cannot allocate ", msg);
   2616 		else
   2617 			abend("memory allocation failure", NULL);
   2618 	}
   2619 
   2620 	return (buf);
   2621 }
   2622 
   2623 void *
   2624 my_malloc(size_t size, const char *msg)
   2625 {
   2626 	return (my_realloc(NULL, size, msg));
   2627 }
   2628 
   2629 int
   2630 wait4all()
   2631 {
   2632 	int i;
   2633 	pid_t pid;
   2634 	int rc = 0;
   2635 	int status;
   2636 
   2637 	for (i = 0; i < 10; i++) {
   2638 		while ((pid = wait(&status)) != -1) {
   2639 			/* return exit() code of the created process */
   2640 			if (pid == created) {
   2641 				if (WIFEXITED(status))
   2642 					rc = WEXITSTATUS(status);
   2643 				else
   2644 					rc |= 0x80; /* +128 to indicate sig */
   2645 			}
   2646 		}
   2647 		if (errno != EINTR && errno != ERESTART)
   2648 			break;
   2649 	}
   2650 
   2651 	if (i >= 10)	/* repeated interrupts */
   2652 		rc = 2;
   2653 
   2654 	return (rc);
   2655 }
   2656 
   2657 void
   2658 letgo(private_t *pri)
   2659 {
   2660 	(void) printf("%s\t*** process otherwise traced, releasing ...\n",
   2661 		pri->pname);
   2662 }
   2663 
   2664 /*
   2665  * Test for empty set.
   2666  * support routine used by isemptyset() macro.
   2667  */
   2668 int
   2669 is_empty(const uint32_t *sp,	/* pointer to set (array of int32's) */
   2670 	size_t n)		/* number of int32's in set */
   2671 {
   2672 	if (n) {
   2673 		do {
   2674 			if (*sp++)
   2675 				return (FALSE);
   2676 		} while (--n);
   2677 	}
   2678 
   2679 	return (TRUE);
   2680 }
   2681 
   2682 /*
   2683  * OR the second set into the first.
   2684  * The sets must be the same size.
   2685  */
   2686 void
   2687 or_set(uint32_t *sp1, const uint32_t *sp2, size_t n)
   2688 {
   2689 	if (n) {
   2690 		do {
   2691 			*sp1++ |= *sp2++;
   2692 		} while (--n);
   2693 	}
   2694 }
   2695