xref: /titanic_52/usr/src/cmd/truss/main.c (revision 8793b36b40d14ad0a0fecc97738dc118a928f46c)
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