xref: /minix/minix/usr.bin/trace/trace.c (revision 045e0ed3)
1 /* trace(1) - the MINIX3 system call tracer - by D.C. van Moolenbroek */
2 
3 #include "inc.h"
4 
5 #include <signal.h>
6 #include <sys/wait.h>
7 #include <unistd.h>
8 #include <err.h>
9 
10 /* Global variables, used only for a subset of the command line options. */
11 int timestamps;		 /* 0 = none, 1 = time w/o usecs, 2 = time w/usecs */
12 int allnames;		 /* FALSE = structure field names, TRUE = all names */
13 unsigned int valuesonly; /* 0 = normal, 1 = no symbols, 2 = no structures */
14 unsigned int verbose;	 /* 0 = essentials, 1 = elaborate, 2 = everything */
15 
16 /* Local variables, for signal handling. */
17 static int got_signal, got_info;
18 
19 /*
20  * Signal handler for signals that are supposed to make us terminate.  Let the
21  * main loop do the actual work, since it might be in the middle of processing
22  * a process status change right now.
23  */
24 static void
25 sig_handler(int __unused sig)
26 {
27 
28 	got_signal = TRUE;
29 
30 }
31 
32 /*
33  * Signal handler for the SIGINFO signal.  Let the main loop report on all
34  * processes currenty being traced.  Since SIGINFO is sent to the current
35  * process group, traced children may get the signal as well.  This is both
36  * intentional and impossible to prevent.
37  */
38 static void
39 info_handler(int __unused sig)
40 {
41 
42 	got_info = TRUE;
43 }
44 
45 /*
46  * Print a list of traced processes and their call status.  We must not
47  * interfere with actual process output, so perform out-of-band printing
48  * (with info lines rather than lines prefixed by each process's PID).
49  */
50 static void
51 list_info(void)
52 {
53 	struct trace_proc *proc;
54 	int no_call, in_call;
55 
56 	put_newline();
57 
58 	for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) {
59 		/*
60 		 * When attaching to an existing process, there is no way to
61 		 * find out whether the process is in a system call or not.
62 		 */
63 		no_call = (proc->trace_flags & TF_NOCALL);
64 		in_call = (proc->trace_flags & TF_INCALL);
65 		assert(!in_call || !no_call);
66 
67 		put_fmt(NULL, "Tracing %s (pid %d), %s%s%s", proc->name,
68 		    proc->pid, no_call ? "call status unknown" :
69 		    (in_call ? "in a " : "not in a call"),
70 		    in_call ? call_name(proc) : "",
71 		    in_call ? " call" : "");
72 		put_newline();
73 	}
74 }
75 
76 /*
77  * Either we have just started or attached to the given process, it the process
78  * has performed a successful execve() call.  Obtain the new process name, and
79  * print a banner for it.
80  */
81 static void
82 new_exec(struct trace_proc * proc)
83 {
84 
85 	/* Failure to obtain the process name is worrisome, but not fatal.. */
86 	if (kernel_get_name(proc->pid, proc->name, sizeof(proc->name)) < 0)
87 		strlcpy(proc->name, "<unknown>", sizeof(proc->name));
88 
89 	put_newline();
90 	put_fmt(proc, "Tracing %s (pid %d)", proc->name, proc->pid);
91 	put_newline();
92 }
93 
94 /*
95  * We have started or attached to a process.  Set the appropriate flags, and
96  * print a banner showing that we are now tracing it.
97  */
98 static void
99 new_proc(struct trace_proc * proc, int follow_fork)
100 {
101 	int fl;
102 
103 	/* Set the desired tracing options. */
104 	fl = TO_ALTEXEC;
105 	if (follow_fork) fl |= TO_TRACEFORK;
106 
107 	(void)ptrace(T_SETOPT, proc->pid, 0, fl);
108 
109 	/*
110 	 * When attaching to an arbitrary process, this process might be in the
111 	 * middle of an execve().  Now that we have enabled TO_ALTEXEC, we may
112 	 * now get a SIGSTOP signal next.  Guard against this by marking the
113 	 * first system call as a possible execve().
114 	 */
115 	if ((proc->trace_flags & (TF_ATTACH | TF_STOPPING)) == TF_ATTACH)
116 		proc->trace_flags |= TF_EXEC;
117 
118 	new_exec(proc);
119 }
120 
121 /*
122  * A process has terminated or is being detached.  Print the resulting status.
123  */
124 static void
125 discard_proc(struct trace_proc * proc, int status)
126 {
127 	const char *signame;
128 
129 	/*
130 	 * The exit() calls are of type no-return, meaning they are expected
131 	 * not to return.  However, calls of this type may in fact return an
132 	 * error, in which case the error must be printed.  Thus, such calls
133 	 * are not actually finished until the end of the call-leave phase.
134 	 * For exit() calls, a successful call will never get to the call-leave
135 	 * phase.  The result is that such calls will end up being shown as
136 	 * suspended, which is unintuitive.  To counter this, we pretend that a
137 	 * clean process exit is in fact preceded by a call-leave event, thus
138 	 * allowing the call to be printed without suspension.  An example:
139 	 *
140 	 *        3| exit(0) <..>
141 	 *        2| setsid() = 2
142 	 * [A]    3| exit(0)
143 	 *        3| Process exited normally with code 0
144 	 *
145 	 * The [A] line is the result of the following code.
146 	 */
147 	if (WIFEXITED(status) && (proc->trace_flags & TF_INCALL))
148 		call_leave(proc, TRUE /*skip*/);
149 
150 	put_newline();
151 	if (WIFEXITED(status)) {
152 		put_fmt(proc, "Process exited normally with code %d",
153 		    WEXITSTATUS(status));
154 	} else if (WIFSIGNALED(status)) {
155 		if ((signame = get_signal_name(WTERMSIG(status))) != NULL)
156 			put_fmt(proc, "Process terminated from signal %s",
157 			    signame);
158 		else
159 			put_fmt(proc, "Process terminated from signal %d",
160 			    WTERMSIG(status));
161 	} else if (WIFSTOPPED(status))
162 		put_text(proc, "Process detached");
163 	else
164 		put_fmt(proc, "Bogus wait result (%04x)", status);
165 	put_newline();
166 
167 	proc_del(proc);
168 }
169 
170 /*
171  * The given process has been stopped on a system call, either entering or
172  * leaving that call.
173  */
174 static void
175 handle_call(struct trace_proc * proc, int show_stack)
176 {
177 	reg_t pc, sp;
178 	int class, skip, new_ctx;
179 
180 	proc->trace_flags &= ~TF_NOCALL;
181 
182 	if (proc->trace_flags & TF_SKIP) {
183 		/* Skip the call leave phase after a successful execve(). */
184 		proc->trace_flags &= ~(TF_INCALL | TF_SKIP);
185 	} else if (!(proc->trace_flags & TF_INCALL)) {
186 		/*
187 		 * The call_enter call returns the class of the call:
188 		 * TC_NORMAL, TC_EXEC, or TC_SIGRET.  TC_EXEC means that an
189 		 * execve() call is being performed.  This means that if a
190 		 * SIGSTOP follows for the current process, the process has
191 		 * successfully started a different executable.  TC_SIGRET
192 		 * means that if successful, the call will have a bogus return
193 		 * value.  TC_NORMAL means that the call requires no exception.
194 		 */
195 		class = call_enter(proc, show_stack);
196 
197 		switch (class) {
198 		case TC_NORMAL:
199 			break;
200 		case TC_EXEC:
201 			proc->trace_flags |= TF_EXEC;
202 			break;
203 		case TC_SIGRET:
204 			proc->trace_flags |= TF_CTX_SKIP;
205 			break;
206 		default:
207 			assert(0);
208 		}
209 
210 		/* Save the current program counter and stack pointer. */
211 		if (!kernel_get_context(proc->pid, &pc, &sp, NULL /*fp*/)) {
212 			proc->last_pc = pc;
213 			proc->last_sp = sp;
214 		} else
215 			proc->last_pc = proc->last_sp = 0;
216 
217 		proc->trace_flags |= TF_INCALL;
218 	} else {
219 		/*
220 		 * Check if the program counter or stack pointer have changed
221 		 * during the system call.  If so, this is a strong indication
222 		 * that a sigreturn call has succeeded, and thus its result
223 		 * must be skipped, since the result register will not contain
224 		 * the result of the call.
225 		 */
226 		new_ctx = (proc->last_pc != 0 &&
227 		    !kernel_get_context(proc->pid, &pc, &sp, NULL /*fp*/) &&
228 		    (pc != proc->last_pc || sp != proc->last_sp));
229 
230 		skip = ((proc->trace_flags & TF_CTX_SKIP) && new_ctx);
231 
232 		call_leave(proc, skip);
233 
234 		/*
235 		 * On such context changes, also print a short dashed line.
236 		 * This helps in identifying signal handler invocations,
237 		 * although it is not reliable for that purpose: no dashed line
238 		 * will be printed if a signal handler is invoked while the
239 		 * process is not making a system call.
240 		 */
241 		if (new_ctx) {
242 			put_text(proc, "---");
243 			put_newline();
244 		}
245 
246 		proc->trace_flags &= ~(TF_INCALL | TF_CTX_SKIP | TF_EXEC);
247 	}
248 }
249 
250 /*
251  * The given process has received the given signal.  Report the receipt.  Due
252  * to the way that signal handling with traced processes works, the signal may
253  * in fact be delivered to the process much later, or never--a problem inherent
254  * to the way signals are handled in PM right now (namely, deferring signal
255  * delivery would let the traced process block signals meant for the tracer).
256  */
257 static void
258 report_signal(struct trace_proc * proc, int sig, int show_stack)
259 {
260 	const char *signame;
261 
262 	/*
263 	 * Print a stack trace only if we are not in a call; otherwise, we
264 	 * would simply get the same stack trace twice and mess up the output
265 	 * in the process, because call suspension is not expected if we are
266 	 * tracing a single process only.
267 	 * FIXME: the check should be for whether we actually print the call..
268 	 */
269 	if (show_stack && !(proc->trace_flags & TF_INCALL))
270 		kernel_put_stacktrace(proc);
271 
272 	/*
273 	 * If this process is in the middle of a call, the signal will be
274 	 * printed within the call.  This will always happen on the call split,
275 	 * that is, between the call's entering (out) and leaving (in) phases.
276 	 * This also means that the recording of the call-enter phase may be
277 	 * replayed more than once, and the call may be suspended more than
278 	 * once--after all, a signal is not necessarily followed immediately
279 	 * by the call result.  If the process is not in the middle of a call,
280 	 * the signal will end up on a separate line.  In both cases, multiple
281 	 * consecutive signals may be printed right after one another.  The
282 	 * following scenario shows a number of possible combinations:
283 	 *
284 	 *       2| foo(<..>
285 	 *       3| ** SIGHUP ** ** SIGUSR1 **
286 	 *       3| bar() = <..>
287 	 *       2|*foo(** SIGUSR1 ** ** SIGUSR2 ** <..>
288 	 *       3|*bar() = ** SIGCHLD ** 0
289 	 *       2|*foo(** SIGINT ** &0xef852000) = -1 [EINTR]
290 	 *       3| kill(3, SIGTERM) = ** SIGTERM ** <..>
291 	 *       3| Process terminated from signal SIGTERM
292 	 */
293 
294 	call_replay(proc);
295 
296 	if (!valuesonly && (signame = get_signal_name(sig)) != NULL)
297 		put_fmt(proc, "** %s **", signame);
298 	else
299 		put_fmt(proc, "** SIGNAL %d **", sig);
300 
301 	put_space(proc);
302 
303 	output_flush();
304 }
305 
306 /*
307  * Wait for the given process ID to stop on the given signal.  Upon success,
308  * the function will return zero.  Upon failure, it will return -1, and errno
309  * will be either set to an error code, or to zero in order to indicate that
310  * the process exited instead.
311  */
312 static int
313 wait_sig(pid_t pid, int sig)
314 {
315 	int status;
316 
317 	for (;;) {
318 		if (waitpid(pid, &status, 0) == -1) {
319 			if (errno == EINTR) continue;
320 
321 			return -1;
322 		}
323 
324 		if (!WIFSTOPPED(status)) {
325 			/* The process terminated just now. */
326 			errno = 0;
327 
328 			return -1;
329 		}
330 
331 		if (WSTOPSIG(status) == sig)
332 			break;
333 
334 		(void)ptrace(T_RESUME, pid, 0, WSTOPSIG(status));
335 	}
336 
337 	return 0;
338 }
339 
340 /*
341  * Attach to the given process, and wait for the resulting SIGSTOP signal.
342  * Other signals may arrive first; we pass these on to the process without
343  * reporting them, thus logically modelling them as having arrived before we
344  * attached to the process.  The process might also exit in the meantime,
345  * typically as a result of a lethal signal; following the same logical model,
346  * we pretend the process did not exist in the first place.  Since the SIGSTOP
347  * signal will be pending right after attaching to the process, this procedure
348  * will never block.
349  */
350 static int
351 attach(pid_t pid)
352 {
353 
354 	if (ptrace(T_ATTACH, pid, 0, 0) != 0) {
355 		warn("Unable to attach to pid %d", pid);
356 
357 		return -1;
358 	}
359 
360 	if (wait_sig(pid, SIGSTOP) != 0) {
361 		/* If the process terminated, report it as not found. */
362 		if (errno == 0)
363 			errno = ESRCH;
364 
365 		warn("Unable to attach to pid %d", pid);
366 
367 		return -1;
368 	}
369 
370 	/* Verify that we can read values from the kernel at all. */
371 	if (kernel_check(pid) == FALSE) {
372 		(void)ptrace(T_DETACH, pid, 0, 0);
373 
374 		warnx("Kernel magic check failed, recompile trace(1)");
375 
376 		return -1;
377 	}
378 
379 	/*
380 	 * System services are managed by RS, which prevents them from
381 	 * being traced properly by PM.  Attaching to a service could
382 	 * therefore cause problems, so we should detach immediately.
383 	 */
384 	if (kernel_is_service(pid) == TRUE) {
385 		(void)ptrace(T_DETACH, pid, 0, 0);
386 
387 		warnx("Cannot attach to system services!");
388 
389 		return -1;
390 	}
391 
392 	return 0;
393 }
394 
395 /*
396  * Detach from all processes, knowning that they were all processes to which we
397  * attached explicitly (i.e., not started by us) and are all currently stopped.
398  */
399 static void
400 detach_stopped(void)
401 {
402 	struct trace_proc *proc;
403 
404 	for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc))
405 		(void)ptrace(T_DETACH, proc->pid, 0, 0);
406 }
407 
408 /*
409  * Start detaching from all processes to which we previously attached.  The
410  * function is expected to return before detaching is completed, and the caller
411  * must deal with the new situation appropriately.  Do not touch any processes
412  * started by us (to allow graceful termination), unless force is set, in which
413  * case those processes are killed.
414  */
415 static void
416 detach_running(int force)
417 {
418 	struct trace_proc *proc;
419 
420 	for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) {
421 		if (proc->trace_flags & TF_ATTACH) {
422 			/* Already detaching?  Then do nothing. */
423 			if (proc->trace_flags & TF_DETACH)
424 				continue;
425 
426 			if (!(proc->trace_flags & TF_STOPPING))
427 				(void)kill(proc->pid, SIGSTOP);
428 
429 			proc->trace_flags |= TF_DETACH | TF_STOPPING;
430 		} else {
431 			/*
432 			 * The child processes may be ignoring SIGINTs, so upon
433 			 * the second try, force them to terminate.
434 			 */
435 			if (force)
436 				(void)kill(proc->pid, SIGKILL);
437 		}
438 	}
439 }
440 
441 /*
442  * Print command usage.
443  */
444 static void __dead
445 usage(void)
446 {
447 
448 	(void)fprintf(stderr, "usage: %s [-fgNstVv] [-o file] [-p pid] "
449 	    "[command]\n", getprogname());
450 
451 	exit(EXIT_FAILURE);
452 }
453 
454 /*
455  * The main function of the system call tracer.
456  */
457 int
458 main(int argc, char * argv[])
459 {
460 	struct trace_proc *proc;
461 	const char *output_file;
462 	int status, sig, follow_fork, show_stack, grouping, first_signal;
463 	pid_t pid, last_pid;
464 	int c, error;
465 
466 	setprogname(argv[0]);
467 
468 	proc_init();
469 
470 	follow_fork = FALSE;
471 	show_stack = FALSE;
472 	grouping = FALSE;
473 	output_file = NULL;
474 
475 	timestamps = 0;
476 	allnames = FALSE;
477 	verbose = 0;
478 	valuesonly = 0;
479 
480 	while ((c = getopt(argc, argv, "fgNstVvo:p:")) != -1) {
481 		switch (c) {
482 		case 'f':
483 			follow_fork = TRUE;
484 			break;
485 		case 'g':
486 			grouping = TRUE;
487 			break;
488 		case 'N':
489 			allnames = TRUE;
490 			break;
491 		case 's':
492 			show_stack = TRUE;
493 			break;
494 		case 't':
495 			timestamps++;
496 			break;
497 		case 'V':
498 			valuesonly++;
499 			break;
500 		case 'v':
501 			verbose++;
502 			break;
503 		case 'o':
504 			output_file = optarg;
505 			break;
506 		case 'p':
507 			pid = atoi(optarg);
508 			if (pid <= 0)
509 				usage();
510 
511 			if (proc_get(pid) == NULL && proc_add(pid) == NULL)
512 				err(EXIT_FAILURE, NULL);
513 
514 			break;
515 		default:
516 			usage();
517 		}
518 	}
519 
520 	argv += optind;
521 	argc -= optind;
522 
523 	first_signal = TRUE;
524 	got_signal = FALSE;
525 	got_info = FALSE;
526 
527 	signal(SIGINT, sig_handler);
528 	signal(SIGINFO, info_handler);
529 
530 	/* Attach to any processes for which PIDs were given. */
531 	for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) {
532 		if (attach(proc->pid) != 0) {
533 			/*
534 			 * Detach from the processes that we have attached to
535 			 * so far, i.e. the ones with the TF_ATTACH flag.
536 			 */
537 			detach_stopped();
538 
539 			return EXIT_FAILURE;
540 		}
541 
542 		proc->trace_flags = TF_ATTACH | TF_NOCALL;
543 	}
544 
545 	/* If a command is given, start a child that executes the command. */
546 	if (argc >= 1) {
547 		pid = fork();
548 
549 		switch (pid) {
550 		case -1:
551 			warn("Unable to fork");
552 
553 			detach_stopped();
554 
555 			return EXIT_FAILURE;
556 
557 		case 0:
558 			(void)ptrace(T_OK, 0, 0, 0);
559 
560 			(void)execvp(argv[0], argv);
561 
562 			err(EXIT_FAILURE, "Unable to start %s", argv[0]);
563 
564 		default:
565 			break;
566 		}
567 
568 		/*
569 		 * The first signal will now be SIGTRAP from the execvp(),
570 		 * unless that fails, in which case the child will terminate.
571 		 */
572 		if (wait_sig(pid, SIGTRAP) != 0) {
573 			/*
574 			 * If the child exited, the most likely cause is a
575 			 * failure to execute the command.  Let the child
576 			 * report the error, and do not say anything here.
577 			 */
578 			if (errno != 0)
579 				warn("Unable to start process");
580 
581 			detach_stopped();
582 
583 			return EXIT_FAILURE;
584 		}
585 
586 		/* If we haven't already, perform the kernel magic check. */
587 		if (proc_count() == 0 && kernel_check(pid) == FALSE) {
588 			warnx("Kernel magic check failed, recompile trace(1)");
589 
590 			(void)kill(pid, SIGKILL);
591 
592 			detach_stopped();
593 
594 			return EXIT_FAILURE;
595 		}
596 
597 		if ((proc = proc_add(pid)) == NULL) {
598 			warn(NULL);
599 
600 			(void)kill(pid, SIGKILL);
601 
602 			detach_stopped();
603 
604 			return EXIT_FAILURE;
605 		}
606 
607 		proc->trace_flags = 0;
608 	} else
609 		pid = -1;
610 
611 	/* The user will have to give us at least one process to trace. */
612 	if (proc_count() == 0)
613 		usage();
614 
615 	/*
616 	 * Open an alternative output file if needed.  After that, standard
617 	 * error should no longer be used directly, and all output has to go
618 	 * through the output module.
619 	 */
620 	if (output_init(output_file) < 0) {
621 		warn("Unable to open output file");
622 
623 		if (pid > 0)
624 			(void)kill(pid, SIGKILL);
625 
626 		detach_stopped();
627 
628 		return EXIT_FAILURE;
629 	}
630 
631 	/*
632 	 * All the traced processes are currently stopped.  Initialize, report,
633 	 * and resume them.
634 	 */
635 	for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) {
636 		new_proc(proc, follow_fork);
637 
638 		(void)ptrace(T_SYSCALL, proc->pid, 0, 0);
639 	}
640 
641 	/*
642 	 * Handle events until there are no traced processes left.
643 	 */
644 	last_pid = 0;
645 	error = FALSE;
646 
647 	for (;;) {
648 		/* If an output error occurred, exit as soon as possible. */
649 		if (!error && output_error()) {
650 			detach_running(TRUE /*force*/);
651 
652 			error = TRUE;
653 		}
654 
655 		/*
656 		 * If the user pressed ^C once, start detaching the processes
657 		 * that we did not start, if any.  If the user pressed ^C
658 		 * twice, kill the process that we did start, if any.
659 		 */
660 		if (got_signal) {
661 			detach_running(!first_signal);
662 
663 			got_signal = FALSE;
664 			first_signal = FALSE;
665 		}
666 
667 		/* Upon getting SIGINFO, print a list of traced processes. */
668 		if (got_info) {
669 			list_info();
670 
671 			got_info = FALSE;
672 		}
673 
674 		/*
675 		 * Block until something happens to a traced process.  If
676 		 * enabled from the command line, first try waiting for the
677 		 * last process for which we got results, so as to reduce call
678 		 * suspensions a bit.
679 		 */
680 		if (grouping && last_pid > 0 &&
681 		    waitpid(last_pid, &status, WNOHANG) > 0)
682 			pid = last_pid;
683 		else
684 		    if ((pid = waitpid(-1, &status, 0)) <= 0) {
685 			if (pid == -1 && errno == EINTR) continue;
686 			if (pid == -1 && errno == ECHILD) break; /* all done */
687 
688 			put_fmt(NULL, "Unexpected waitpid failure: %s",
689 			    (pid == 0) ? "No result" : strerror(errno));
690 			put_newline();
691 
692 			/*
693 			 * We need waitpid to function correctly in order to
694 			 * detach from any attached processes, so we can do
695 			 * little more than just exit, effectively killing all
696 			 * traced processes.
697 			 */
698 			return EXIT_FAILURE;
699 		}
700 
701 		last_pid = 0;
702 
703 		/* Get the trace data structure for the process. */
704 		if ((proc = proc_get(pid)) == NULL) {
705 			/*
706 			 * The waitpid() call returned the status of a process
707 			 * that we have not yet seen.  This must be a newly
708 			 * forked child.  If it is not stopped, it must have
709 			 * died immediately, and we choose not to report it.
710 			 */
711 			if (!WIFSTOPPED(status))
712 				continue;
713 
714 			if ((proc = proc_add(pid)) == NULL) {
715 				put_fmt(NULL,
716 				    "Error attaching to new child %d: %s",
717 				    pid, strerror(errno));
718 				put_newline();
719 
720 				/*
721 				 * Out of memory allocating a new child object!
722 				 * We can not trace this child, so just let it
723 				 * run free by detaching from it.
724 				 */
725 				if (WSTOPSIG(status) != SIGSTOP) {
726 					(void)ptrace(T_RESUME, pid, 0,
727 					    WSTOPSIG(status));
728 
729 					if (wait_sig(pid, SIGSTOP) != 0)
730 						continue; /* it died.. */
731 				}
732 
733 				(void)ptrace(T_DETACH, pid, 0, 0);
734 
735 				continue;
736 			}
737 
738 			/*
739 			 * We must specify TF_ATTACH here, even though it may
740 			 * be a child of a process we started, in which case it
741 			 * should be killed when we exit.  We do not keep track
742 			 * of ancestry though, so better safe than sorry.
743 			 */
744 			proc->trace_flags = TF_ATTACH | TF_STOPPING;
745 
746 			new_proc(proc, follow_fork);
747 
748 			/* Repeat entering the fork call for the child. */
749 			handle_call(proc, show_stack);
750 		}
751 
752 		/* If the process died, report its status and clean it up. */
753 		if (!WIFSTOPPED(status)) {
754 			discard_proc(proc, status);
755 
756 			continue;
757 		}
758 
759 		sig = WSTOPSIG(status);
760 
761 		if (sig == SIGSTOP && (proc->trace_flags & TF_STOPPING)) {
762 			/* We expected the process to be stopped; now it is. */
763 			proc->trace_flags &= ~TF_STOPPING;
764 
765 			if (proc->trace_flags & TF_DETACH) {
766 				if (ptrace(T_DETACH, proc->pid, 0, 0) == 0)
767 					discard_proc(proc, status);
768 
769 				/*
770 				 * If detaching failed, the process must have
771 				 * died, and we'll get notified through wait().
772 				 */
773 				continue;
774 			}
775 
776 			sig = 0;
777 		} else if (sig == SIGSTOP && (proc->trace_flags & TF_EXEC)) {
778 			/* The process has performed a successful execve(). */
779 			call_leave(proc, TRUE /*skip*/);
780 
781 			put_text(proc, "---");
782 
783 			new_exec(proc);
784 
785 			/*
786 			 * A successful execve() has no result, in the sense
787 			 * that there is no reply message.  We should therefore
788 			 * not even try to copy in the reply message from the
789 			 * original location, because it will be invalid.
790 			 * Thus, we skip the exec's call leave phase entirely.
791 			 */
792 			proc->trace_flags &= ~TF_EXEC;
793 			proc->trace_flags |= TF_SKIP;
794 
795 			sig = 0;
796 		} else if (sig == SIGTRAP) {
797 			/* The process is entering or leaving a system call. */
798 			if (!(proc->trace_flags & TF_DETACH))
799 				handle_call(proc, show_stack);
800 
801 			sig = 0;
802 		} else {
803 			/* The process has received a signal. */
804 			report_signal(proc, sig, show_stack);
805 
806 			/*
807 			 * Only in this case do we pass the signal to the
808 			 * traced process.
809 			 */
810 		}
811 
812 		/*
813 		 * Resume process execution.  If this call fails, the process
814 		 * has probably died.  We will find out soon enough.
815 		 */
816 		(void)ptrace(T_SYSCALL, proc->pid, 0, sig);
817 
818 		last_pid = proc->pid;
819 	}
820 
821 	return (error) ? EXIT_FAILURE : EXIT_SUCCESS;
822 }
823