strace.c revision df790130ff66b7cb9b3499210bae21a5baede111
1/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "defs.h"
32#include <stdarg.h>
33#include <sys/param.h>
34#include <fcntl.h>
35#include <sys/resource.h>
36#include <sys/wait.h>
37#include <sys/stat.h>
38#include <pwd.h>
39#include <grp.h>
40#include <dirent.h>
41#include <sys/utsname.h>
42#if defined(IA64)
43# include <asm/ptrace_offsets.h>
44#endif
45/* In some libc, these aren't declared. Do it ourself: */
46extern char **environ;
47extern int optind;
48extern char *optarg;
49
50
51#if defined __NR_tkill
52# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
53#else
54   /* kill() may choose arbitrarily the target task of the process group
55      while we later wait on a that specific TID.  PID process waits become
56      TID task specific waits for a process under ptrace(2).  */
57# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
58# define my_tkill(tid, sig) kill((tid), (sig))
59#endif
60
61#undef KERNEL_VERSION
62#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
63
64cflag_t cflag = CFLAG_NONE;
65unsigned int followfork = 0;
66unsigned int ptrace_setoptions = 0;
67unsigned int xflag = 0;
68bool debug_flag = 0;
69bool Tflag = 0;
70bool qflag = 0;
71/* Which WSTOPSIG(status) value marks syscall traps? */
72static unsigned int syscall_trap_sig = SIGTRAP;
73static unsigned int tflag = 0;
74static bool iflag = 0;
75static bool rflag = 0;
76static bool print_pid_pfx = 0;
77
78/* -I n */
79enum {
80    INTR_NOT_SET        = 0,
81    INTR_ANYWHERE       = 1, /* don't block/ignore any signals */
82    INTR_WHILE_WAIT     = 2, /* block fatal signals while decoding syscall. default */
83    INTR_NEVER          = 3, /* block fatal signals. default if '-o FILE PROG' */
84    INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
85    NUM_INTR_OPTS
86};
87static int opt_intr;
88/* We play with signal mask only if this mode is active: */
89#define interactive (opt_intr == INTR_WHILE_WAIT)
90
91/*
92 * daemonized_tracer supports -D option.
93 * With this option, strace forks twice.
94 * Unlike normal case, with -D *grandparent* process exec's,
95 * becoming a traced process. Child exits (this prevents traced process
96 * from having children it doesn't expect to have), and grandchild
97 * attaches to grandparent similarly to strace -p PID.
98 * This allows for more transparent interaction in cases
99 * when process and its parent are communicating via signals,
100 * wait() etc. Without -D, strace process gets lodged in between,
101 * disrupting parent<->child link.
102 */
103static bool daemonized_tracer = 0;
104
105#ifdef USE_SEIZE
106static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
107# define use_seize (post_attach_sigstop == 0)
108#else
109# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
110# define use_seize 0
111#endif
112
113/* Sometimes we want to print only succeeding syscalls. */
114bool not_failing_only = 0;
115
116/* Show path associated with fd arguments */
117bool show_fd_path = 0;
118
119/* are we filtering traces based on paths? */
120bool tracing_paths = 0;
121
122static bool detach_on_execve = 0;
123static bool skip_startup_execve = 0;
124
125static int exit_code = 0;
126static int strace_child = 0;
127static int strace_tracer_pid = 0;
128
129static char *username = NULL;
130static uid_t run_uid;
131static gid_t run_gid;
132
133unsigned int max_strlen = DEFAULT_STRLEN;
134static int acolumn = DEFAULT_ACOLUMN;
135static char *acolumn_spaces;
136
137static char *outfname = NULL;
138/* If -ff, points to stderr. Else, it's our common output log */
139static FILE *shared_log;
140
141struct tcb *printing_tcp = NULL;
142static struct tcb *current_tcp;
143
144static struct tcb **tcbtab;
145static unsigned int nprocs, tcbtabsize;
146static const char *progname;
147
148static unsigned os_release; /* generated from uname()'s u.release */
149
150static int detach(struct tcb *tcp);
151static int trace(void);
152static void cleanup(void);
153static void interrupt(int sig);
154static sigset_t empty_set, blocked_set;
155
156#ifdef HAVE_SIG_ATOMIC_T
157static volatile sig_atomic_t interrupted;
158#else
159static volatile int interrupted;
160#endif
161
162#ifndef HAVE_STRERROR
163
164#if !HAVE_DECL_SYS_ERRLIST
165extern int sys_nerr;
166extern char *sys_errlist[];
167#endif
168
169const char *
170strerror(int err_no)
171{
172	static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
173
174	if (err_no < 1 || err_no >= sys_nerr) {
175		sprintf(buf, "Unknown error %d", err_no);
176		return buf;
177	}
178	return sys_errlist[err_no];
179}
180
181#endif /* HAVE_STERRROR */
182
183static void
184usage(FILE *ofp, int exitval)
185{
186	fprintf(ofp, "\
187usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
188              [-a column] [-o file] [-s strsize] [-P path]...\n\
189              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
190   or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
191              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
192-c -- count time, calls, and errors for each syscall and report summary\n\
193-C -- like -c but also print regular output\n\
194-d -- enable debug output to stderr\n\
195-D -- run tracer process as a detached grandchild, not as parent\n\
196-f -- follow forks, -ff -- with output into separate files\n\
197-F -- attempt to follow vforks (deprecated, use -f)\n\
198-i -- print instruction pointer at time of syscall\n\
199-q -- suppress messages about attaching, detaching, etc.\n\
200-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
201-T -- print time spent in each syscall\n\
202-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
203-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
204-y -- print paths associated with file descriptor arguments\n\
205-h -- print help message, -V -- print version\n\
206-a column -- alignment COLUMN for printing syscall results (default %d)\n\
207-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
208   options: trace, abbrev, verbose, raw, signal, read, or write\n\
209-I interruptible --\n\
210   1: no signals are blocked\n\
211   2: fatal signals are blocked while decoding syscall (default)\n\
212   3: fatal signals are always blocked (default if '-o FILE PROG')\n\
213   4: fatal signals and SIGTSTP (^Z) are always blocked\n\
214      (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
215-o file -- send trace output to FILE instead of stderr\n\
216-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
217-p pid -- trace process with process id PID, may be repeated\n\
218-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
219-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
220-u username -- run command as username handling setuid and/or setgid\n\
221-E var=val -- put var=val in the environment for command\n\
222-E var -- remove var from the environment for command\n\
223-P path -- trace accesses to path\n\
224"
225/* this is broken, so don't document it
226-z -- print only succeeding syscalls\n\
227 */
228/* experimental, don't document it yet (option letter may change in the future!)
229-b -- detach on successful execve\n\
230 */
231, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
232	exit(exitval);
233}
234
235static void die(void) __attribute__ ((noreturn));
236static void die(void)
237{
238	if (strace_tracer_pid == getpid()) {
239		cflag = 0;
240		cleanup();
241	}
242	exit(1);
243}
244
245static void verror_msg(int err_no, const char *fmt, va_list p)
246{
247	char *msg;
248
249	fflush(NULL);
250
251	/* We want to print entire message with single fprintf to ensure
252	 * message integrity if stderr is shared with other programs.
253	 * Thus we use vasprintf + single fprintf.
254	 */
255	msg = NULL;
256	if (vasprintf(&msg, fmt, p) >= 0) {
257		if (err_no)
258			fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
259		else
260			fprintf(stderr, "%s: %s\n", progname, msg);
261		free(msg);
262	} else {
263		/* malloc in vasprintf failed, try it without malloc */
264		fprintf(stderr, "%s: ", progname);
265		vfprintf(stderr, fmt, p);
266		if (err_no)
267			fprintf(stderr, ": %s\n", strerror(err_no));
268		else
269			putc('\n', stderr);
270	}
271	/* We don't switch stderr to buffered, thus fprintf(stderr)
272	 * always flushes its output and this is not necessary: */
273	/* fflush(stderr); */
274}
275
276void error_msg(const char *fmt, ...)
277{
278	va_list p;
279	va_start(p, fmt);
280	verror_msg(0, fmt, p);
281	va_end(p);
282}
283
284void error_msg_and_die(const char *fmt, ...)
285{
286	va_list p;
287	va_start(p, fmt);
288	verror_msg(0, fmt, p);
289	die();
290}
291
292void perror_msg(const char *fmt, ...)
293{
294	va_list p;
295	va_start(p, fmt);
296	verror_msg(errno, fmt, p);
297	va_end(p);
298}
299
300void perror_msg_and_die(const char *fmt, ...)
301{
302	va_list p;
303	va_start(p, fmt);
304	verror_msg(errno, fmt, p);
305	die();
306}
307
308void die_out_of_memory(void)
309{
310	static bool recursed = 0;
311	if (recursed)
312		exit(1);
313	recursed = 1;
314	error_msg_and_die("Out of memory");
315}
316
317static void
318error_opt_arg(int opt, const char *arg)
319{
320	error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
321}
322
323/* Glue for systems without a MMU that cannot provide fork() */
324#ifdef HAVE_FORK
325# define strace_vforked 0
326#else
327# define strace_vforked 1
328# define fork()         vfork()
329#endif
330
331#ifdef USE_SEIZE
332static int
333ptrace_attach_or_seize(int pid)
334{
335	int r;
336	if (!use_seize)
337		return ptrace(PTRACE_ATTACH, pid, 0, 0);
338	r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
339	if (r)
340		return r;
341	r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
342	return r;
343}
344#else
345# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
346#endif
347
348/*
349 * Used when we want to unblock stopped traced process.
350 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
351 * Returns 0 on success or if error was ESRCH
352 * (presumably process was killed while we talk to it).
353 * Otherwise prints error message and returns -1.
354 */
355static int
356ptrace_restart(int op, struct tcb *tcp, int sig)
357{
358	int err;
359	const char *msg;
360
361	errno = 0;
362	ptrace(op, tcp->pid, (void *) 0, (long) sig);
363	err = errno;
364	if (!err)
365		return 0;
366
367	msg = "SYSCALL";
368	if (op == PTRACE_CONT)
369		msg = "CONT";
370	if (op == PTRACE_DETACH)
371		msg = "DETACH";
372#ifdef PTRACE_LISTEN
373	if (op == PTRACE_LISTEN)
374		msg = "LISTEN";
375#endif
376	/*
377	 * Why curcol != 0? Otherwise sometimes we get this:
378	 *
379	 * 10252 kill(10253, SIGKILL)              = 0
380	 *  <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
381	 *
382	 * 10252 died after we retrieved syscall exit data,
383	 * but before we tried to restart it. Log looks ugly.
384	 */
385	if (current_tcp && current_tcp->curcol != 0) {
386		tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
387		line_ended();
388	}
389	if (err == ESRCH)
390		return 0;
391	errno = err;
392	perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
393	return -1;
394}
395
396static void
397set_cloexec_flag(int fd)
398{
399	int flags, newflags;
400
401	flags = fcntl(fd, F_GETFD);
402	if (flags < 0) {
403		/* Can happen only if fd is bad.
404		 * Should never happen: if it does, we have a bug
405		 * in the caller. Therefore we just abort
406		 * instead of propagating the error.
407		 */
408		perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
409	}
410
411	newflags = flags | FD_CLOEXEC;
412	if (flags == newflags)
413		return;
414
415	fcntl(fd, F_SETFD, newflags); /* never fails */
416}
417
418static void kill_save_errno(pid_t pid, int sig)
419{
420	int saved_errno = errno;
421
422	(void) kill(pid, sig);
423	errno = saved_errno;
424}
425
426/*
427 * When strace is setuid executable, we have to swap uids
428 * before and after filesystem and process management operations.
429 */
430static void
431swap_uid(void)
432{
433	int euid = geteuid(), uid = getuid();
434
435	if (euid != uid && setreuid(euid, uid) < 0) {
436		perror_msg_and_die("setreuid");
437	}
438}
439
440#if _LFS64_LARGEFILE
441# define fopen_for_output fopen64
442#else
443# define fopen_for_output fopen
444#endif
445
446static FILE *
447strace_fopen(const char *path)
448{
449	FILE *fp;
450
451	swap_uid();
452	fp = fopen_for_output(path, "w");
453	if (!fp)
454		perror_msg_and_die("Can't fopen '%s'", path);
455	swap_uid();
456	set_cloexec_flag(fileno(fp));
457	return fp;
458}
459
460static int popen_pid = 0;
461
462#ifndef _PATH_BSHELL
463# define _PATH_BSHELL "/bin/sh"
464#endif
465
466/*
467 * We cannot use standard popen(3) here because we have to distinguish
468 * popen child process from other processes we trace, and standard popen(3)
469 * does not export its child's pid.
470 */
471static FILE *
472strace_popen(const char *command)
473{
474	FILE *fp;
475	int fds[2];
476
477	swap_uid();
478	if (pipe(fds) < 0)
479		perror_msg_and_die("pipe");
480
481	set_cloexec_flag(fds[1]); /* never fails */
482
483	popen_pid = vfork();
484	if (popen_pid == -1)
485		perror_msg_and_die("vfork");
486
487	if (popen_pid == 0) {
488		/* child */
489		close(fds[1]);
490		if (fds[0] != 0) {
491			if (dup2(fds[0], 0))
492				perror_msg_and_die("dup2");
493			close(fds[0]);
494		}
495		execl(_PATH_BSHELL, "sh", "-c", command, NULL);
496		perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
497	}
498
499	/* parent */
500	close(fds[0]);
501	swap_uid();
502	fp = fdopen(fds[1], "w");
503	if (!fp)
504		die_out_of_memory();
505	return fp;
506}
507
508void
509tprintf(const char *fmt, ...)
510{
511	va_list args;
512
513	va_start(args, fmt);
514	if (current_tcp) {
515		int n = vfprintf(current_tcp->outf, fmt, args);
516		if (n < 0) {
517			if (current_tcp->outf != stderr)
518				perror(outfname == NULL
519				       ? "<writing to pipe>" : outfname);
520		} else
521			current_tcp->curcol += n;
522	}
523	va_end(args);
524}
525
526void
527tprints(const char *str)
528{
529	if (current_tcp) {
530		int n = fputs(str, current_tcp->outf);
531		if (n >= 0) {
532			current_tcp->curcol += strlen(str);
533			return;
534		}
535		if (current_tcp->outf != stderr)
536			perror(!outfname ? "<writing to pipe>" : outfname);
537	}
538}
539
540void
541line_ended(void)
542{
543	if (current_tcp) {
544		current_tcp->curcol = 0;
545		fflush(current_tcp->outf);
546	}
547	if (printing_tcp) {
548		printing_tcp->curcol = 0;
549		printing_tcp = NULL;
550	}
551}
552
553void
554printleader(struct tcb *tcp)
555{
556	/* If -ff, "previous tcb we printed" is always the same as current,
557	 * because we have per-tcb output files.
558	 */
559	if (followfork >= 2)
560		printing_tcp = tcp;
561
562	if (printing_tcp) {
563		current_tcp = printing_tcp;
564		if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
565			/*
566			 * case 1: we have a shared log (i.e. not -ff), and last line
567			 * wasn't finished (same or different tcb, doesn't matter).
568			 * case 2: split log, we are the same tcb, but our last line
569			 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
570			 */
571			tprints(" <unfinished ...>\n");
572			printing_tcp->curcol = 0;
573		}
574	}
575
576	printing_tcp = tcp;
577	current_tcp = tcp;
578	current_tcp->curcol = 0;
579
580	if (print_pid_pfx)
581		tprintf("%-5d ", tcp->pid);
582	else if (nprocs > 1 && !outfname)
583		tprintf("[pid %5u] ", tcp->pid);
584
585	if (tflag) {
586		char str[sizeof("HH:MM:SS")];
587		struct timeval tv, dtv;
588		static struct timeval otv;
589
590		gettimeofday(&tv, NULL);
591		if (rflag) {
592			if (otv.tv_sec == 0)
593				otv = tv;
594			tv_sub(&dtv, &tv, &otv);
595			tprintf("%6ld.%06ld ",
596				(long) dtv.tv_sec, (long) dtv.tv_usec);
597			otv = tv;
598		}
599		else if (tflag > 2) {
600			tprintf("%ld.%06ld ",
601				(long) tv.tv_sec, (long) tv.tv_usec);
602		}
603		else {
604			time_t local = tv.tv_sec;
605			strftime(str, sizeof(str), "%T", localtime(&local));
606			if (tflag > 1)
607				tprintf("%s.%06ld ", str, (long) tv.tv_usec);
608			else
609				tprintf("%s ", str);
610		}
611	}
612	if (iflag)
613		printcall(tcp);
614}
615
616void
617tabto(void)
618{
619	if (current_tcp->curcol < acolumn)
620		tprints(acolumn_spaces + current_tcp->curcol);
621}
622
623/* Should be only called directly *after successful attach* to a tracee.
624 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
625 * may create bogus empty FILE.<nonexistant_pid>, and then die.
626 */
627static void
628newoutf(struct tcb *tcp)
629{
630	tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
631	if (followfork >= 2) {
632		char name[520 + sizeof(int) * 3];
633		sprintf(name, "%.512s.%u", outfname, tcp->pid);
634		tcp->outf = strace_fopen(name);
635	}
636}
637
638static void
639expand_tcbtab(void)
640{
641	/* Allocate some more TCBs and expand the table.
642	   We don't want to relocate the TCBs because our
643	   callers have pointers and it would be a pain.
644	   So tcbtab is a table of pointers.  Since we never
645	   free the TCBs, we allocate a single chunk of many.  */
646	int i = tcbtabsize;
647	struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
648	struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
649	if (!newtab || !newtcbs)
650		die_out_of_memory();
651	tcbtabsize *= 2;
652	tcbtab = newtab;
653	while (i < tcbtabsize)
654		tcbtab[i++] = newtcbs++;
655}
656
657static struct tcb *
658alloctcb(int pid)
659{
660	int i;
661	struct tcb *tcp;
662
663	if (nprocs == tcbtabsize)
664		expand_tcbtab();
665
666	for (i = 0; i < tcbtabsize; i++) {
667		tcp = tcbtab[i];
668		if ((tcp->flags & TCB_INUSE) == 0) {
669			memset(tcp, 0, sizeof(*tcp));
670			tcp->pid = pid;
671			tcp->flags = TCB_INUSE;
672#if SUPPORTED_PERSONALITIES > 1
673			tcp->currpers = current_personality;
674#endif
675			nprocs++;
676			if (debug_flag)
677				fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
678			return tcp;
679		}
680	}
681	error_msg_and_die("bug in alloctcb");
682}
683
684static void
685droptcb(struct tcb *tcp)
686{
687	if (tcp->pid == 0)
688		return;
689
690	nprocs--;
691	if (debug_flag)
692		fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
693
694	if (tcp->outf) {
695		if (followfork >= 2) {
696			if (tcp->curcol != 0)
697				fprintf(tcp->outf, " <detached ...>\n");
698			fclose(tcp->outf);
699		} else {
700			if (printing_tcp == tcp && tcp->curcol != 0)
701				fprintf(tcp->outf, " <detached ...>\n");
702			fflush(tcp->outf);
703		}
704	}
705
706	if (current_tcp == tcp)
707		current_tcp = NULL;
708	if (printing_tcp == tcp)
709		printing_tcp = NULL;
710
711	memset(tcp, 0, sizeof(*tcp));
712}
713
714/* detach traced process; continue with sig
715 * Never call DETACH twice on the same process as both unattached and
716 * attached-unstopped processes give the same ESRCH.  For unattached process we
717 * would SIGSTOP it and wait for its SIGSTOP notification forever.
718 */
719static int
720detach(struct tcb *tcp)
721{
722	int error;
723	int status, sigstop_expected;
724
725	if (tcp->flags & TCB_BPTSET)
726		clearbpt(tcp);
727
728	/*
729	 * Linux wrongly insists the child be stopped
730	 * before detaching.  Arghh.  We go through hoops
731	 * to make a clean break of things.
732	 */
733#if defined(SPARC)
734#undef PTRACE_DETACH
735#define PTRACE_DETACH PTRACE_SUNDETACH
736#endif
737
738	error = 0;
739	sigstop_expected = 0;
740	if (tcp->flags & TCB_ATTACHED) {
741		/*
742		 * We attached but possibly didn't see the expected SIGSTOP.
743		 * We must catch exactly one as otherwise the detached process
744		 * would be left stopped (process state T).
745		 */
746		sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
747		error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
748		if (error == 0) {
749			/* On a clear day, you can see forever. */
750		}
751		else if (errno != ESRCH) {
752			/* Shouldn't happen. */
753			perror("detach: ptrace(PTRACE_DETACH, ...)");
754		}
755		else if (my_tkill(tcp->pid, 0) < 0) {
756			if (errno != ESRCH)
757				perror("detach: checking sanity");
758		}
759		else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
760			if (errno != ESRCH)
761				perror("detach: stopping child");
762		}
763		else
764			sigstop_expected = 1;
765	}
766
767	if (sigstop_expected) {
768		for (;;) {
769#ifdef __WALL
770			if (waitpid(tcp->pid, &status, __WALL) < 0) {
771				if (errno == ECHILD) /* Already gone.  */
772					break;
773				if (errno != EINVAL) {
774					perror("detach: waiting");
775					break;
776				}
777#endif /* __WALL */
778				/* No __WALL here.  */
779				if (waitpid(tcp->pid, &status, 0) < 0) {
780					if (errno != ECHILD) {
781						perror("detach: waiting");
782						break;
783					}
784#ifdef __WCLONE
785					/* If no processes, try clones.  */
786					if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
787						if (errno != ECHILD)
788							perror("detach: waiting");
789						break;
790					}
791#endif /* __WCLONE */
792				}
793#ifdef __WALL
794			}
795#endif
796			if (!WIFSTOPPED(status)) {
797				/* Au revoir, mon ami. */
798				break;
799			}
800			if (WSTOPSIG(status) == SIGSTOP) {
801				ptrace_restart(PTRACE_DETACH, tcp, 0);
802				break;
803			}
804			error = ptrace_restart(PTRACE_CONT, tcp,
805					WSTOPSIG(status) == syscall_trap_sig ? 0
806					: WSTOPSIG(status));
807			if (error < 0)
808				break;
809		}
810	}
811
812	if (!qflag && (tcp->flags & TCB_ATTACHED))
813		fprintf(stderr, "Process %u detached\n", tcp->pid);
814
815	droptcb(tcp);
816
817	return error;
818}
819
820static void
821process_opt_p_list(char *opt)
822{
823	while (*opt) {
824		/*
825		 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
826		 * pidof uses space as delim, pgrep uses newline. :(
827		 */
828		int pid;
829		char *delim = opt + strcspn(opt, ", \n\t");
830		char c = *delim;
831
832		*delim = '\0';
833		pid = string_to_uint(opt);
834		if (pid <= 0) {
835			error_msg_and_die("Invalid process id: '%s'", opt);
836		}
837		if (pid == strace_tracer_pid) {
838			error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
839		}
840		*delim = c;
841		alloctcb(pid);
842		if (c == '\0')
843			break;
844		opt = delim + 1;
845	}
846}
847
848static void
849startup_attach(void)
850{
851	int tcbi;
852	struct tcb *tcp;
853
854	/*
855	 * Block user interruptions as we would leave the traced
856	 * process stopped (process state T) if we would terminate in
857	 * between PTRACE_ATTACH and wait4() on SIGSTOP.
858	 * We rely on cleanup() from this point on.
859	 */
860	if (interactive)
861		sigprocmask(SIG_BLOCK, &blocked_set, NULL);
862
863	if (daemonized_tracer) {
864		pid_t pid = fork();
865		if (pid < 0) {
866			perror_msg_and_die("fork");
867		}
868		if (pid) { /* parent */
869			/*
870			 * Wait for grandchild to attach to straced process
871			 * (grandparent). Grandchild SIGKILLs us after it attached.
872			 * Grandparent's wait() is unblocked by our death,
873			 * it proceeds to exec the straced program.
874			 */
875			pause();
876			_exit(0); /* paranoia */
877		}
878		/* grandchild */
879		/* We will be the tracer process. Remember our new pid: */
880		strace_tracer_pid = getpid();
881	}
882
883	for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
884		tcp = tcbtab[tcbi];
885
886		if (!(tcp->flags & TCB_INUSE))
887			continue;
888
889		/* Is this a process we should attach to, but not yet attached? */
890		if (tcp->flags & TCB_ATTACHED)
891			continue; /* no, we already attached it */
892
893		if (followfork && !daemonized_tracer) {
894			char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
895			DIR *dir;
896
897			sprintf(procdir, "/proc/%d/task", tcp->pid);
898			dir = opendir(procdir);
899			if (dir != NULL) {
900				unsigned int ntid = 0, nerr = 0;
901				struct dirent *de;
902
903				while ((de = readdir(dir)) != NULL) {
904					struct tcb *cur_tcp;
905					int tid;
906
907					if (de->d_fileno == 0)
908						continue;
909					/* we trust /proc filesystem */
910					tid = atoi(de->d_name);
911					if (tid <= 0)
912						continue;
913					++ntid;
914					if (ptrace_attach_or_seize(tid) < 0) {
915						++nerr;
916						if (debug_flag)
917							fprintf(stderr, "attach to pid %d failed\n", tid);
918						continue;
919					}
920					if (debug_flag)
921						fprintf(stderr, "attach to pid %d succeeded\n", tid);
922					cur_tcp = tcp;
923					if (tid != tcp->pid)
924						cur_tcp = alloctcb(tid);
925					cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
926					newoutf(cur_tcp);
927				}
928				closedir(dir);
929				if (interactive) {
930					sigprocmask(SIG_SETMASK, &empty_set, NULL);
931					if (interrupted)
932						goto ret;
933					sigprocmask(SIG_BLOCK, &blocked_set, NULL);
934				}
935				ntid -= nerr;
936				if (ntid == 0) {
937					perror("attach: ptrace(PTRACE_ATTACH, ...)");
938					droptcb(tcp);
939					continue;
940				}
941				if (!qflag) {
942					fprintf(stderr, ntid > 1
943? "Process %u attached with %u threads\n"
944: "Process %u attached\n",
945						tcp->pid, ntid);
946				}
947				if (!(tcp->flags & TCB_ATTACHED)) {
948					/* -p PID, we failed to attach to PID itself
949					 * but did attach to some of its sibling threads.
950					 * Drop PID's tcp.
951					 */
952					droptcb(tcp);
953				}
954				continue;
955			} /* if (opendir worked) */
956		} /* if (-f) */
957		if (ptrace_attach_or_seize(tcp->pid) < 0) {
958			perror("attach: ptrace(PTRACE_ATTACH, ...)");
959			droptcb(tcp);
960			continue;
961		}
962		tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
963		newoutf(tcp);
964		if (debug_flag)
965			fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
966
967		if (daemonized_tracer) {
968			/*
969			 * Make parent go away.
970			 * Also makes grandparent's wait() unblock.
971			 */
972			kill(getppid(), SIGKILL);
973		}
974
975		if (!qflag)
976			fprintf(stderr,
977				"Process %u attached\n",
978				tcp->pid);
979	} /* for each tcbtab[] */
980
981 ret:
982	if (interactive)
983		sigprocmask(SIG_SETMASK, &empty_set, NULL);
984}
985
986static void
987startup_child(char **argv)
988{
989	struct stat statbuf;
990	const char *filename;
991	char pathname[MAXPATHLEN];
992	int pid = 0;
993	struct tcb *tcp;
994
995	filename = argv[0];
996	if (strchr(filename, '/')) {
997		if (strlen(filename) > sizeof pathname - 1) {
998			errno = ENAMETOOLONG;
999			perror_msg_and_die("exec");
1000		}
1001		strcpy(pathname, filename);
1002	}
1003#ifdef USE_DEBUGGING_EXEC
1004	/*
1005	 * Debuggers customarily check the current directory
1006	 * first regardless of the path but doing that gives
1007	 * security geeks a panic attack.
1008	 */
1009	else if (stat(filename, &statbuf) == 0)
1010		strcpy(pathname, filename);
1011#endif /* USE_DEBUGGING_EXEC */
1012	else {
1013		const char *path;
1014		int m, n, len;
1015
1016		for (path = getenv("PATH"); path && *path; path += m) {
1017			const char *colon = strchr(path, ':');
1018			if (colon) {
1019				n = colon - path;
1020				m = n + 1;
1021			}
1022			else
1023				m = n = strlen(path);
1024			if (n == 0) {
1025				if (!getcwd(pathname, MAXPATHLEN))
1026					continue;
1027				len = strlen(pathname);
1028			}
1029			else if (n > sizeof pathname - 1)
1030				continue;
1031			else {
1032				strncpy(pathname, path, n);
1033				len = n;
1034			}
1035			if (len && pathname[len - 1] != '/')
1036				pathname[len++] = '/';
1037			strcpy(pathname + len, filename);
1038			if (stat(pathname, &statbuf) == 0 &&
1039			    /* Accept only regular files
1040			       with some execute bits set.
1041			       XXX not perfect, might still fail */
1042			    S_ISREG(statbuf.st_mode) &&
1043			    (statbuf.st_mode & 0111))
1044				break;
1045		}
1046	}
1047	if (stat(pathname, &statbuf) < 0) {
1048		perror_msg_and_die("Can't stat '%s'", filename);
1049	}
1050	strace_child = pid = fork();
1051	if (pid < 0) {
1052		perror_msg_and_die("fork");
1053	}
1054	if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1055	 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
1056	) {
1057		pid = getpid();
1058		if (shared_log != stderr)
1059			close(fileno(shared_log));
1060		if (!daemonized_tracer && !use_seize) {
1061			if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
1062				perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
1063			}
1064		}
1065
1066		if (username != NULL) {
1067			uid_t run_euid = run_uid;
1068			gid_t run_egid = run_gid;
1069
1070			if (statbuf.st_mode & S_ISUID)
1071				run_euid = statbuf.st_uid;
1072			if (statbuf.st_mode & S_ISGID)
1073				run_egid = statbuf.st_gid;
1074			/*
1075			 * It is important to set groups before we
1076			 * lose privileges on setuid.
1077			 */
1078			if (initgroups(username, run_gid) < 0) {
1079				perror_msg_and_die("initgroups");
1080			}
1081			if (setregid(run_gid, run_egid) < 0) {
1082				perror_msg_and_die("setregid");
1083			}
1084			if (setreuid(run_uid, run_euid) < 0) {
1085				perror_msg_and_die("setreuid");
1086			}
1087		}
1088		else if (geteuid() != 0)
1089			setreuid(run_uid, run_uid);
1090
1091		if (!daemonized_tracer) {
1092			/*
1093			 * Induce a ptrace stop. Tracer (our parent)
1094			 * will resume us with PTRACE_SYSCALL and display
1095			 * the immediately following execve syscall.
1096			 * Can't do this on NOMMU systems, we are after
1097			 * vfork: parent is blocked, stopping would deadlock.
1098			 */
1099			if (!strace_vforked)
1100				kill(pid, SIGSTOP);
1101		} else {
1102			alarm(3);
1103			/* we depend on SIGCHLD set to SIG_DFL by init code */
1104			/* if it happens to be SIG_IGN'ed, wait won't block */
1105			wait(NULL);
1106			alarm(0);
1107		}
1108
1109		execv(pathname, argv);
1110		perror_msg_and_die("exec");
1111	}
1112
1113	/* We are the tracer */
1114
1115	if (!daemonized_tracer) {
1116		if (!use_seize) {
1117			/* child did PTRACE_TRACEME, nothing to do in parent */
1118		} else {
1119			if (!strace_vforked) {
1120				/* Wait until child stopped itself */
1121				int status;
1122				while (waitpid(pid, &status, WSTOPPED) < 0) {
1123					if (errno == EINTR)
1124						continue;
1125					perror_msg_and_die("waitpid");
1126				}
1127				if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
1128					kill_save_errno(pid, SIGKILL);
1129					perror_msg_and_die("Unexpected wait status %x", status);
1130				}
1131			}
1132			/* Else: vforked case, we have no way to sync.
1133			 * Just attach to it as soon as possible.
1134			 * This means that we may miss a few first syscalls...
1135			 */
1136
1137			if (ptrace_attach_or_seize(pid)) {
1138				kill_save_errno(pid, SIGKILL);
1139				perror_msg_and_die("Can't attach to %d", pid);
1140			}
1141			if (!strace_vforked)
1142				kill(pid, SIGCONT);
1143		}
1144		tcp = alloctcb(pid);
1145		if (!strace_vforked)
1146			tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
1147		else
1148			tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
1149		newoutf(tcp);
1150	}
1151	else {
1152		/* With -D, *we* are child here, IOW: different pid. Fetch it: */
1153		strace_tracer_pid = getpid();
1154		/* The tracee is our parent: */
1155		pid = getppid();
1156		alloctcb(pid);
1157		/* attaching will be done later, by startup_attach */
1158		/* note: we don't do newoutf(tcp) here either! */
1159	}
1160}
1161
1162/*
1163 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
1164 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
1165 * and then see which options are supported by the kernel.
1166 */
1167static void
1168test_ptrace_setoptions_followfork(void)
1169{
1170	int pid, expected_grandchild = 0, found_grandchild = 0;
1171	const unsigned int test_options = PTRACE_O_TRACECLONE |
1172					  PTRACE_O_TRACEFORK |
1173					  PTRACE_O_TRACEVFORK;
1174
1175	pid = fork();
1176	if (pid < 0)
1177		perror_msg_and_die("fork");
1178	if (pid == 0) {
1179		pid = getpid();
1180		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1181			perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1182					   __func__);
1183		kill_save_errno(pid, SIGSTOP);
1184		if (fork() < 0)
1185			perror_msg_and_die("fork");
1186		_exit(0);
1187	}
1188
1189	while (1) {
1190		int status, tracee_pid;
1191
1192		errno = 0;
1193		tracee_pid = wait(&status);
1194		if (tracee_pid <= 0) {
1195			if (errno == EINTR)
1196				continue;
1197			if (errno == ECHILD)
1198				break;
1199			kill_save_errno(pid, SIGKILL);
1200			perror_msg_and_die("%s: unexpected wait result %d",
1201					   __func__, tracee_pid);
1202		}
1203		if (WIFEXITED(status)) {
1204			if (WEXITSTATUS(status)) {
1205				if (tracee_pid != pid)
1206					kill_save_errno(pid, SIGKILL);
1207				error_msg_and_die("%s: unexpected exit status %u",
1208						  __func__, WEXITSTATUS(status));
1209			}
1210			continue;
1211		}
1212		if (WIFSIGNALED(status)) {
1213			if (tracee_pid != pid)
1214				kill_save_errno(pid, SIGKILL);
1215			error_msg_and_die("%s: unexpected signal %u",
1216					  __func__, WTERMSIG(status));
1217		}
1218		if (!WIFSTOPPED(status)) {
1219			if (tracee_pid != pid)
1220				kill_save_errno(tracee_pid, SIGKILL);
1221			kill_save_errno(pid, SIGKILL);
1222			error_msg_and_die("%s: unexpected wait status %x",
1223					  __func__, status);
1224		}
1225		if (tracee_pid != pid) {
1226			found_grandchild = tracee_pid;
1227			if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1228				kill_save_errno(tracee_pid, SIGKILL);
1229				kill_save_errno(pid, SIGKILL);
1230				perror_msg_and_die("PTRACE_CONT doesn't work");
1231			}
1232			continue;
1233		}
1234		switch (WSTOPSIG(status)) {
1235		case SIGSTOP:
1236			if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1237			    && errno != EINVAL && errno != EIO)
1238				perror_msg("PTRACE_SETOPTIONS");
1239			break;
1240		case SIGTRAP:
1241			if (status >> 16 == PTRACE_EVENT_FORK) {
1242				long msg = 0;
1243
1244				if (ptrace(PTRACE_GETEVENTMSG, pid,
1245					   NULL, (long) &msg) == 0)
1246					expected_grandchild = msg;
1247			}
1248			break;
1249		}
1250		if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1251			kill_save_errno(pid, SIGKILL);
1252			perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1253		}
1254	}
1255	if (expected_grandchild && expected_grandchild == found_grandchild) {
1256		ptrace_setoptions |= test_options;
1257		if (debug_flag)
1258			fprintf(stderr, "ptrace_setoptions = %#x\n",
1259				ptrace_setoptions);
1260		return;
1261	}
1262	error_msg("Test for PTRACE_O_TRACECLONE failed, "
1263		  "giving up using this feature.");
1264}
1265
1266/*
1267 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1268 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1269 * and then see whether it will stop with (SIGTRAP | 0x80).
1270 *
1271 * Use of this option enables correct handling of user-generated SIGTRAPs,
1272 * and SIGTRAPs generated by special instructions such as int3 on x86:
1273 * _start:	.globl	_start
1274 *		int3
1275 *		movl	$42, %ebx
1276 *		movl	$1, %eax
1277 *		int	$0x80
1278 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1279 */
1280static void
1281test_ptrace_setoptions_for_all(void)
1282{
1283	const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1284					  PTRACE_O_TRACEEXEC;
1285	int pid;
1286	int it_worked = 0;
1287
1288	pid = fork();
1289	if (pid < 0)
1290		perror_msg_and_die("fork");
1291
1292	if (pid == 0) {
1293		pid = getpid();
1294		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1295			/* Note: exits with exitcode 1 */
1296			perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1297					   __func__);
1298		kill(pid, SIGSTOP);
1299		_exit(0); /* parent should see entry into this syscall */
1300	}
1301
1302	while (1) {
1303		int status, tracee_pid;
1304
1305		errno = 0;
1306		tracee_pid = wait(&status);
1307		if (tracee_pid <= 0) {
1308			if (errno == EINTR)
1309				continue;
1310			kill_save_errno(pid, SIGKILL);
1311			perror_msg_and_die("%s: unexpected wait result %d",
1312					   __func__, tracee_pid);
1313		}
1314		if (WIFEXITED(status)) {
1315			if (WEXITSTATUS(status) == 0)
1316				break;
1317			error_msg_and_die("%s: unexpected exit status %u",
1318					  __func__, WEXITSTATUS(status));
1319		}
1320		if (WIFSIGNALED(status)) {
1321			error_msg_and_die("%s: unexpected signal %u",
1322					  __func__, WTERMSIG(status));
1323		}
1324		if (!WIFSTOPPED(status)) {
1325			kill(pid, SIGKILL);
1326			error_msg_and_die("%s: unexpected wait status %x",
1327					  __func__, status);
1328		}
1329		if (WSTOPSIG(status) == SIGSTOP) {
1330			/*
1331			 * We don't check "options aren't accepted" error.
1332			 * If it happens, we'll never get (SIGTRAP | 0x80),
1333			 * and thus will decide to not use the option.
1334			 * IOW: the outcome of the test will be correct.
1335			 */
1336			if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1337			    && errno != EINVAL && errno != EIO)
1338				perror_msg("PTRACE_SETOPTIONS");
1339		}
1340		if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1341			it_worked = 1;
1342		}
1343		if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1344			kill_save_errno(pid, SIGKILL);
1345			perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1346		}
1347	}
1348
1349	if (it_worked) {
1350		syscall_trap_sig = (SIGTRAP | 0x80);
1351		ptrace_setoptions |= test_options;
1352		if (debug_flag)
1353			fprintf(stderr, "ptrace_setoptions = %#x\n",
1354				ptrace_setoptions);
1355		return;
1356	}
1357
1358	error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1359		  "giving up using this feature.");
1360}
1361
1362# ifdef USE_SEIZE
1363static void
1364test_ptrace_seize(void)
1365{
1366	int pid;
1367
1368	pid = fork();
1369	if (pid < 0)
1370		perror_msg_and_die("fork");
1371
1372	if (pid == 0) {
1373		pause();
1374		_exit(0);
1375	}
1376
1377	/* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap.  After
1378	 * attaching tracee continues to run unless a trap condition occurs.
1379	 * PTRACE_SEIZE doesn't affect signal or group stop state.
1380	 */
1381	if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1382		post_attach_sigstop = 0; /* this sets use_seize to 1 */
1383	} else if (debug_flag) {
1384		fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1385	}
1386
1387	kill(pid, SIGKILL);
1388
1389	while (1) {
1390		int status, tracee_pid;
1391
1392		errno = 0;
1393		tracee_pid = waitpid(pid, &status, 0);
1394		if (tracee_pid <= 0) {
1395			if (errno == EINTR)
1396				continue;
1397			perror_msg_and_die("%s: unexpected wait result %d",
1398					 __func__, tracee_pid);
1399		}
1400		if (WIFSIGNALED(status)) {
1401			return;
1402		}
1403		error_msg_and_die("%s: unexpected wait status %x",
1404				__func__, status);
1405	}
1406}
1407# else /* !USE_SEIZE */
1408#  define test_ptrace_seize() ((void)0)
1409# endif
1410
1411static unsigned
1412get_os_release(void)
1413{
1414	unsigned rel;
1415	const char *p;
1416	struct utsname u;
1417	if (uname(&u) < 0)
1418		perror_msg_and_die("uname");
1419	/* u.release has this form: "3.2.9[-some-garbage]" */
1420	rel = 0;
1421	p = u.release;
1422	for (;;) {
1423		if (!(*p >= '0' && *p <= '9'))
1424			error_msg_and_die("Bad OS release string: '%s'", u.release);
1425		/* Note: this open-codes KERNEL_VERSION(): */
1426		rel = (rel << 8) | atoi(p);
1427		if (rel >= KERNEL_VERSION(1,0,0))
1428			break;
1429		while (*p >= '0' && *p <= '9')
1430			p++;
1431		if (*p != '.')
1432			error_msg_and_die("Bad OS release string: '%s'", u.release);
1433		p++;
1434	}
1435	return rel;
1436}
1437
1438/*
1439 * Initialization part of main() was eating much stack (~0.5k),
1440 * which was unused after init.
1441 * We can reuse it if we move init code into a separate function.
1442 *
1443 * Don't want main() to inline us and defeat the reason
1444 * we have a separate function.
1445 */
1446static void __attribute__ ((noinline))
1447init(int argc, char *argv[])
1448{
1449	struct tcb *tcp;
1450	int c, i;
1451	int optF = 0;
1452	struct sigaction sa;
1453
1454	progname = argv[0] ? argv[0] : "strace";
1455
1456	/* Make sure SIGCHLD has the default action so that waitpid
1457	   definitely works without losing track of children.  The user
1458	   should not have given us a bogus state to inherit, but he might
1459	   have.  Arguably we should detect SIG_IGN here and pass it on
1460	   to children, but probably noone really needs that.  */
1461	signal(SIGCHLD, SIG_DFL);
1462
1463	strace_tracer_pid = getpid();
1464
1465	os_release = get_os_release();
1466
1467	/* Allocate the initial tcbtab.  */
1468	tcbtabsize = argc;	/* Surely enough for all -p args.  */
1469	tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1470	if (!tcbtab)
1471		die_out_of_memory();
1472	tcp = calloc(tcbtabsize, sizeof(*tcp));
1473	if (!tcp)
1474		die_out_of_memory();
1475	for (c = 0; c < tcbtabsize; c++)
1476		tcbtab[c] = tcp++;
1477
1478	shared_log = stderr;
1479	set_sortby(DEFAULT_SORTBY);
1480	set_personality(DEFAULT_PERSONALITY);
1481	qualify("trace=all");
1482	qualify("abbrev=all");
1483	qualify("verbose=all");
1484	qualify("signal=all");
1485	while ((c = getopt(argc, argv,
1486		"+bcCdfFhiqrtTvVxyz"
1487		"D"
1488		"a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1489		switch (c) {
1490		case 'b':
1491			detach_on_execve = 1;
1492			break;
1493		case 'c':
1494			if (cflag == CFLAG_BOTH) {
1495				error_msg_and_die("-c and -C are mutually exclusive");
1496			}
1497			cflag = CFLAG_ONLY_STATS;
1498			break;
1499		case 'C':
1500			if (cflag == CFLAG_ONLY_STATS) {
1501				error_msg_and_die("-c and -C are mutually exclusive");
1502			}
1503			cflag = CFLAG_BOTH;
1504			break;
1505		case 'd':
1506			debug_flag = 1;
1507			break;
1508		case 'D':
1509			daemonized_tracer = 1;
1510			break;
1511		case 'F':
1512			optF = 1;
1513			break;
1514		case 'f':
1515			followfork++;
1516			break;
1517		case 'h':
1518			usage(stdout, 0);
1519			break;
1520		case 'i':
1521			iflag = 1;
1522			break;
1523		case 'q':
1524			qflag = 1;
1525			break;
1526		case 'r':
1527			rflag = 1;
1528			/* fall through to tflag++ */
1529		case 't':
1530			tflag++;
1531			break;
1532		case 'T':
1533			Tflag = 1;
1534			break;
1535		case 'x':
1536			xflag++;
1537			break;
1538		case 'y':
1539			show_fd_path = 1;
1540			break;
1541		case 'v':
1542			qualify("abbrev=none");
1543			break;
1544		case 'V':
1545			printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1546			exit(0);
1547			break;
1548		case 'z':
1549			not_failing_only = 1;
1550			break;
1551		case 'a':
1552			acolumn = string_to_uint(optarg);
1553			if (acolumn < 0)
1554				error_opt_arg(c, optarg);
1555			break;
1556		case 'e':
1557			qualify(optarg);
1558			break;
1559		case 'o':
1560			outfname = strdup(optarg);
1561			break;
1562		case 'O':
1563			i = string_to_uint(optarg);
1564			if (i < 0)
1565				error_opt_arg(c, optarg);
1566			set_overhead(i);
1567			break;
1568		case 'p':
1569			process_opt_p_list(optarg);
1570			break;
1571		case 'P':
1572			tracing_paths = 1;
1573			if (pathtrace_select(optarg)) {
1574				error_msg_and_die("Failed to select path '%s'", optarg);
1575			}
1576			break;
1577		case 's':
1578			i = string_to_uint(optarg);
1579			if (i < 0)
1580				error_opt_arg(c, optarg);
1581			max_strlen = i;
1582			break;
1583		case 'S':
1584			set_sortby(optarg);
1585			break;
1586		case 'u':
1587			username = strdup(optarg);
1588			break;
1589		case 'E':
1590			if (putenv(optarg) < 0)
1591				die_out_of_memory();
1592			break;
1593		case 'I':
1594			opt_intr = string_to_uint(optarg);
1595			if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1596				error_opt_arg(c, optarg);
1597			break;
1598		default:
1599			usage(stderr, 1);
1600			break;
1601		}
1602	}
1603	argv += optind;
1604	/* argc -= optind; - no need, argc is not used below */
1605
1606	acolumn_spaces = malloc(acolumn + 1);
1607	if (!acolumn_spaces)
1608		die_out_of_memory();
1609	memset(acolumn_spaces, ' ', acolumn);
1610	acolumn_spaces[acolumn] = '\0';
1611
1612	/* Must have PROG [ARGS], or -p PID. Not both. */
1613	if (!argv[0] == !nprocs)
1614		usage(stderr, 1);
1615
1616	if (nprocs != 0 && daemonized_tracer) {
1617		error_msg_and_die("-D and -p are mutually exclusive");
1618	}
1619
1620	if (!followfork)
1621		followfork = optF;
1622
1623	if (followfork >= 2 && cflag) {
1624		error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
1625	}
1626
1627	/* See if they want to run as another user. */
1628	if (username != NULL) {
1629		struct passwd *pent;
1630
1631		if (getuid() != 0 || geteuid() != 0) {
1632			error_msg_and_die("You must be root to use the -u option");
1633		}
1634		pent = getpwnam(username);
1635		if (pent == NULL) {
1636			error_msg_and_die("Cannot find user '%s'", username);
1637		}
1638		run_uid = pent->pw_uid;
1639		run_gid = pent->pw_gid;
1640	}
1641	else {
1642		run_uid = getuid();
1643		run_gid = getgid();
1644	}
1645
1646	if (followfork)
1647		test_ptrace_setoptions_followfork();
1648	test_ptrace_setoptions_for_all();
1649	test_ptrace_seize();
1650
1651	/* Check if they want to redirect the output. */
1652	if (outfname) {
1653		/* See if they want to pipe the output. */
1654		if (outfname[0] == '|' || outfname[0] == '!') {
1655			/*
1656			 * We can't do the <outfname>.PID funny business
1657			 * when using popen, so prohibit it.
1658			 */
1659			if (followfork >= 2)
1660				error_msg_and_die("Piping the output and -ff are mutually exclusive");
1661			shared_log = strace_popen(outfname + 1);
1662		}
1663		else if (followfork < 2)
1664			shared_log = strace_fopen(outfname);
1665	} else {
1666		/* -ff without -o FILE is the same as single -f */
1667		if (followfork >= 2)
1668			followfork = 1;
1669	}
1670
1671	if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1672		char *buf = malloc(BUFSIZ);
1673		if (!buf)
1674			die_out_of_memory();
1675		setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
1676	}
1677	if (outfname && argv[0]) {
1678		if (!opt_intr)
1679			opt_intr = INTR_NEVER;
1680		qflag = 1;
1681	}
1682	if (!opt_intr)
1683		opt_intr = INTR_WHILE_WAIT;
1684
1685	/* argv[0]	-pPID	-oFILE	Default interactive setting
1686	 * yes		0	0	INTR_WHILE_WAIT
1687	 * no		1	0	INTR_WHILE_WAIT
1688	 * yes		0	1	INTR_NEVER
1689	 * no		1	1	INTR_WHILE_WAIT
1690	 */
1691
1692	/* STARTUP_CHILD must be called before the signal handlers get
1693	   installed below as they are inherited into the spawned process.
1694	   Also we do not need to be protected by them as during interruption
1695	   in the STARTUP_CHILD mode we kill the spawned process anyway.  */
1696	if (argv[0]) {
1697		skip_startup_execve = 1;
1698		startup_child(argv);
1699	}
1700
1701	sigemptyset(&empty_set);
1702	sigemptyset(&blocked_set);
1703	sa.sa_handler = SIG_IGN;
1704	sigemptyset(&sa.sa_mask);
1705	sa.sa_flags = 0;
1706	sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1707	sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1708	if (opt_intr != INTR_ANYWHERE) {
1709		if (opt_intr == INTR_BLOCK_TSTP_TOO)
1710			sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1711		/*
1712		 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1713		 * fatal signals are blocked while syscall stop is processed,
1714		 * and acted on in between, when waiting for new syscall stops.
1715		 * In non-interactive mode, signals are ignored.
1716		 */
1717		if (opt_intr == INTR_WHILE_WAIT) {
1718			sigaddset(&blocked_set, SIGHUP);
1719			sigaddset(&blocked_set, SIGINT);
1720			sigaddset(&blocked_set, SIGQUIT);
1721			sigaddset(&blocked_set, SIGPIPE);
1722			sigaddset(&blocked_set, SIGTERM);
1723			sa.sa_handler = interrupt;
1724		}
1725		/* SIG_IGN, or set handler for these */
1726		sigaction(SIGHUP, &sa, NULL);
1727		sigaction(SIGINT, &sa, NULL);
1728		sigaction(SIGQUIT, &sa, NULL);
1729		sigaction(SIGPIPE, &sa, NULL);
1730		sigaction(SIGTERM, &sa, NULL);
1731	}
1732	if (nprocs != 0 || daemonized_tracer)
1733		startup_attach();
1734
1735	/* Do we want pids printed in our -o OUTFILE?
1736	 * -ff: no (every pid has its own file); or
1737	 * -f: yes (there can be more pids in the future); or
1738	 * -p PID1,PID2: yes (there are already more than one pid)
1739	 */
1740	print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1741}
1742
1743static struct tcb *
1744pid2tcb(int pid)
1745{
1746	int i;
1747
1748	if (pid <= 0)
1749		return NULL;
1750
1751	for (i = 0; i < tcbtabsize; i++) {
1752		struct tcb *tcp = tcbtab[i];
1753		if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1754			return tcp;
1755	}
1756
1757	return NULL;
1758}
1759
1760static void
1761cleanup(void)
1762{
1763	int i;
1764	struct tcb *tcp;
1765	int fatal_sig;
1766
1767	/* 'interrupted' is a volatile object, fetch it only once */
1768	fatal_sig = interrupted;
1769	if (!fatal_sig)
1770		fatal_sig = SIGTERM;
1771
1772	for (i = 0; i < tcbtabsize; i++) {
1773		tcp = tcbtab[i];
1774		if (!(tcp->flags & TCB_INUSE))
1775			continue;
1776		if (debug_flag)
1777			fprintf(stderr,
1778				"cleanup: looking at pid %u\n", tcp->pid);
1779		if (tcp->flags & TCB_STRACE_CHILD) {
1780			kill(tcp->pid, SIGCONT);
1781			kill(tcp->pid, fatal_sig);
1782		}
1783		detach(tcp);
1784	}
1785	if (cflag)
1786		call_summary(shared_log);
1787}
1788
1789static void
1790interrupt(int sig)
1791{
1792	interrupted = sig;
1793}
1794
1795static int
1796trace(void)
1797{
1798	struct rusage ru;
1799	struct rusage *rup = cflag ? &ru : NULL;
1800# ifdef __WALL
1801	static int wait4_options = __WALL;
1802# endif
1803
1804	while (nprocs != 0) {
1805		int pid;
1806		int wait_errno;
1807		int status, sig;
1808		int stopped;
1809		struct tcb *tcp;
1810		unsigned event;
1811
1812		if (interrupted)
1813			return 0;
1814		if (interactive)
1815			sigprocmask(SIG_SETMASK, &empty_set, NULL);
1816# ifdef __WALL
1817		pid = wait4(-1, &status, wait4_options, rup);
1818		if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1819			/* this kernel does not support __WALL */
1820			wait4_options &= ~__WALL;
1821			pid = wait4(-1, &status, wait4_options, rup);
1822		}
1823		if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1824			/* most likely a "cloned" process */
1825			pid = wait4(-1, &status, __WCLONE, rup);
1826			if (pid < 0) {
1827				perror_msg("wait4(__WCLONE) failed");
1828			}
1829		}
1830# else
1831		pid = wait4(-1, &status, 0, rup);
1832# endif /* __WALL */
1833		wait_errno = errno;
1834		if (interactive)
1835			sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1836
1837		if (pid < 0) {
1838			switch (wait_errno) {
1839			case EINTR:
1840				continue;
1841			case ECHILD:
1842				/*
1843				 * We would like to verify this case
1844				 * but sometimes a race in Solbourne's
1845				 * version of SunOS sometimes reports
1846				 * ECHILD before sending us SIGCHILD.
1847				 */
1848				return 0;
1849			default:
1850				errno = wait_errno;
1851				perror_msg("wait");
1852				return -1;
1853			}
1854		}
1855		if (pid == popen_pid) {
1856			if (WIFEXITED(status) || WIFSIGNALED(status))
1857				popen_pid = 0;
1858			continue;
1859		}
1860
1861		event = ((unsigned)status >> 16);
1862		if (debug_flag) {
1863			char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1864			char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1865			strcpy(buf, "???");
1866			if (WIFSIGNALED(status))
1867#ifdef WCOREDUMP
1868				sprintf(buf, "WIFSIGNALED,%ssig=%s",
1869						WCOREDUMP(status) ? "core," : "",
1870						signame(WTERMSIG(status)));
1871#else
1872				sprintf(buf, "WIFSIGNALED,sig=%s",
1873						signame(WTERMSIG(status)));
1874#endif
1875			if (WIFEXITED(status))
1876				sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1877			if (WIFSTOPPED(status))
1878				sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1879#ifdef WIFCONTINUED
1880			if (WIFCONTINUED(status))
1881				strcpy(buf, "WIFCONTINUED");
1882#endif
1883			evbuf[0] = '\0';
1884			if (event != 0) {
1885				static const char *const event_names[] = {
1886					[PTRACE_EVENT_CLONE] = "CLONE",
1887					[PTRACE_EVENT_FORK]  = "FORK",
1888					[PTRACE_EVENT_VFORK] = "VFORK",
1889					[PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1890					[PTRACE_EVENT_EXEC]  = "EXEC",
1891					[PTRACE_EVENT_EXIT]  = "EXIT",
1892				};
1893				const char *e;
1894				if (event < ARRAY_SIZE(event_names))
1895					e = event_names[event];
1896				else {
1897					sprintf(buf, "?? (%u)", event);
1898					e = buf;
1899				}
1900				sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1901			}
1902			fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1903		}
1904
1905		/* Look up 'pid' in our table. */
1906		tcp = pid2tcb(pid);
1907
1908		if (!tcp) {
1909			if (followfork) {
1910				/* This is needed to go with the CLONE_PTRACE
1911				   changes in process.c/util.c: we might see
1912				   the child's initial trap before we see the
1913				   parent return from the clone syscall.
1914				   Leave the child suspended until the parent
1915				   returns from its system call.  Only then
1916				   will we have the association of parent and
1917				   child so that we know how to do clearbpt
1918				   in the child.  */
1919				tcp = alloctcb(pid);
1920				tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1921				newoutf(tcp);
1922				if (!qflag)
1923					fprintf(stderr, "Process %d attached\n",
1924						pid);
1925			} else {
1926				/* This can happen if a clone call used
1927				   CLONE_PTRACE itself.  */
1928				if (WIFSTOPPED(status))
1929					ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1930				error_msg_and_die("Unknown pid: %u", pid);
1931			}
1932		}
1933
1934		/* Under Linux, execve changes pid to thread leader's pid,
1935		 * and we see this changed pid on EVENT_EXEC and later,
1936		 * execve sysexit. Leader "disappears" without exit
1937		 * notification. Let user know that, drop leader's tcb,
1938		 * and fix up pid in execve thread's tcb.
1939		 * Effectively, execve thread's tcb replaces leader's tcb.
1940		 *
1941		 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1942		 * on exit syscall) in multithreaded programs exactly
1943		 * in order to handle this case.
1944		 *
1945		 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1946		 * On 2.6 and earlier, it can return garbage.
1947		 */
1948		if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
1949			FILE *fp;
1950			struct tcb *execve_thread;
1951			long old_pid = 0;
1952
1953			if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1954				goto dont_switch_tcbs;
1955			if (old_pid <= 0 || old_pid == pid)
1956				goto dont_switch_tcbs;
1957			execve_thread = pid2tcb(old_pid);
1958			/* It should be !NULL, but I feel paranoid */
1959			if (!execve_thread)
1960				goto dont_switch_tcbs;
1961
1962			if (execve_thread->curcol != 0) {
1963				/*
1964				 * One case we are here is -ff:
1965				 * try "strace -oLOG -ff test/threaded_execve"
1966				 */
1967				fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1968				/*execve_thread->curcol = 0; - no need, see code below */
1969			}
1970			/* Swap output FILEs (needed for -ff) */
1971			fp = execve_thread->outf;
1972			execve_thread->outf = tcp->outf;
1973			tcp->outf = fp;
1974			/* And their column positions */
1975			execve_thread->curcol = tcp->curcol;
1976			tcp->curcol = 0;
1977			/* Drop leader, but close execve'd thread outfile (if -ff) */
1978			droptcb(tcp);
1979			/* Switch to the thread, reusing leader's outfile and pid */
1980			tcp = execve_thread;
1981			tcp->pid = pid;
1982			if (cflag != CFLAG_ONLY_STATS) {
1983				printleader(tcp);
1984				tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1985				line_ended();
1986				tcp->flags |= TCB_REPRINT;
1987			}
1988		}
1989 dont_switch_tcbs:
1990
1991		if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1992			if (!skip_startup_execve)
1993				detach(tcp);
1994			/* This was initial execve for "strace PROG". Skip. */
1995			skip_startup_execve = 0;
1996		}
1997
1998		/* Set current output file */
1999		current_tcp = tcp;
2000
2001		if (cflag) {
2002			tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2003			tcp->stime = ru.ru_stime;
2004		}
2005
2006		if (WIFSIGNALED(status)) {
2007			if (pid == strace_child)
2008				exit_code = 0x100 | WTERMSIG(status);
2009			if (cflag != CFLAG_ONLY_STATS
2010			    && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2011				printleader(tcp);
2012#ifdef WCOREDUMP
2013				tprintf("+++ killed by %s %s+++\n",
2014					signame(WTERMSIG(status)),
2015					WCOREDUMP(status) ? "(core dumped) " : "");
2016#else
2017				tprintf("+++ killed by %s +++\n",
2018					signame(WTERMSIG(status)));
2019#endif
2020				line_ended();
2021			}
2022			droptcb(tcp);
2023			continue;
2024		}
2025		if (WIFEXITED(status)) {
2026			if (pid == strace_child)
2027				exit_code = WEXITSTATUS(status);
2028			if (cflag != CFLAG_ONLY_STATS) {
2029				printleader(tcp);
2030				tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
2031				line_ended();
2032			}
2033			droptcb(tcp);
2034			continue;
2035		}
2036		if (!WIFSTOPPED(status)) {
2037			fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2038			droptcb(tcp);
2039			continue;
2040		}
2041
2042		/* Is this the very first time we see this tracee stopped? */
2043		if (tcp->flags & TCB_STARTUP) {
2044			if (debug_flag)
2045				fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2046			tcp->flags &= ~TCB_STARTUP;
2047			if (tcp->flags & TCB_BPTSET) {
2048				/*
2049				 * One example is a breakpoint inherited from
2050				 * parent through fork().
2051				 */
2052				if (clearbpt(tcp) < 0) {
2053					/* Pretty fatal */
2054					droptcb(tcp);
2055					cleanup();
2056					return -1;
2057				}
2058			}
2059			if (ptrace_setoptions) {
2060				if (debug_flag)
2061					fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2062				if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2063					if (errno != ESRCH) {
2064						/* Should never happen, really */
2065						perror_msg_and_die("PTRACE_SETOPTIONS");
2066					}
2067				}
2068			}
2069		}
2070
2071		sig = WSTOPSIG(status);
2072
2073		if (event != 0) {
2074			/* Ptrace event */
2075#ifdef USE_SEIZE
2076			if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
2077				/*
2078				 * PTRACE_INTERRUPT-stop or group-stop.
2079				 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2080				 */
2081				if (sig == SIGSTOP
2082				 || sig == SIGTSTP
2083				 || sig == SIGTTIN
2084				 || sig == SIGTTOU
2085				) {
2086					stopped = 1;
2087					goto show_stopsig;
2088				}
2089			}
2090#endif
2091			goto restart_tracee_with_sig_0;
2092		}
2093
2094		/* Is this post-attach SIGSTOP?
2095		 * Interestingly, the process may stop
2096		 * with STOPSIG equal to some other signal
2097		 * than SIGSTOP if we happend to attach
2098		 * just before the process takes a signal.
2099		 */
2100		if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2101			if (debug_flag)
2102				fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2103			tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2104			goto restart_tracee_with_sig_0;
2105		}
2106
2107		if (sig != syscall_trap_sig) {
2108			siginfo_t si;
2109
2110			/* Nonzero (true) if tracee is stopped by signal
2111			 * (as opposed to "tracee received signal").
2112			 * TODO: shouldn't we check for errno == EINVAL too?
2113			 * We can get ESRCH instead, you know...
2114			 */
2115			stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2116#ifdef USE_SEIZE
2117 show_stopsig:
2118#endif
2119			if (cflag != CFLAG_ONLY_STATS
2120			    && (qual_flags[sig] & QUAL_SIGNAL)) {
2121#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2122				long pc = 0;
2123				long psr = 0;
2124
2125				upeek(tcp, PT_CR_IPSR, &psr);
2126				upeek(tcp, PT_CR_IIP, &pc);
2127
2128# define PSR_RI	41
2129				pc += (psr >> PSR_RI) & 0x3;
2130# define PC_FORMAT_STR	" @ %lx"
2131# define PC_FORMAT_ARG	, pc
2132#else
2133# define PC_FORMAT_STR	""
2134# define PC_FORMAT_ARG	/* nothing */
2135#endif
2136				printleader(tcp);
2137				if (!stopped) {
2138					tprintf("--- %s ", signame(sig));
2139					printsiginfo(&si, verbose(tcp));
2140					tprintf(PC_FORMAT_STR " ---\n"
2141						PC_FORMAT_ARG);
2142				} else
2143					tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
2144						signame(sig)
2145						PC_FORMAT_ARG);
2146				line_ended();
2147			}
2148
2149			if (!stopped)
2150				/* It's signal-delivery-stop. Inject the signal */
2151				goto restart_tracee;
2152
2153			/* It's group-stop */
2154#ifdef USE_SEIZE
2155			if (use_seize) {
2156				/*
2157				 * This ends ptrace-stop, but does *not* end group-stop.
2158				 * This makes stopping signals work properly on straced process
2159				 * (that is, process really stops. It used to continue to run).
2160				 */
2161				if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2162					cleanup();
2163					return -1;
2164				}
2165				continue;
2166			}
2167			/* We don't have PTRACE_LISTEN support... */
2168#endif
2169			goto restart_tracee;
2170		}
2171
2172		/* We handled quick cases, we are permitted to interrupt now. */
2173		if (interrupted)
2174			return 0;
2175
2176		/* This should be syscall entry or exit.
2177		 * (Or it still can be that pesky post-execve SIGTRAP!)
2178		 * Handle it.
2179		 */
2180		if (trace_syscall(tcp) < 0) {
2181			/* ptrace() failed in trace_syscall().
2182			 * Likely a result of process disappearing mid-flight.
2183			 * Observed case: exit_group() or SIGKILL terminating
2184			 * all processes in thread group.
2185			 * We assume that ptrace error was caused by process death.
2186			 * We used to detach(tcp) here, but since we no longer
2187			 * implement "detach before death" policy/hack,
2188			 * we can let this process to report its death to us
2189			 * normally, via WIFEXITED or WIFSIGNALED wait status.
2190			 */
2191			continue;
2192		}
2193 restart_tracee_with_sig_0:
2194		sig = 0;
2195 restart_tracee:
2196		/* Remember current print column before continuing. */
2197		if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2198			cleanup();
2199			return -1;
2200		}
2201	}
2202	return 0;
2203}
2204
2205int
2206main(int argc, char *argv[])
2207{
2208	init(argc, argv);
2209
2210	/* Run main tracing loop */
2211	if (trace() < 0)
2212		return 1;
2213
2214	cleanup();
2215	fflush(NULL);
2216	if (exit_code > 0xff) {
2217		/* Avoid potential core file clobbering.  */
2218		struct rlimit rlim = {0, 0};
2219		setrlimit(RLIMIT_CORE, &rlim);
2220
2221		/* Child was killed by a signal, mimic that.  */
2222		exit_code &= 0xff;
2223		signal(exit_code, SIG_DFL);
2224		raise(exit_code);
2225		/* Paranoia - what if this signal is not fatal?
2226		   Exit with 128 + signo then.  */
2227		exit_code += 128;
2228	}
2229
2230	return exit_code;
2231}
2232