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