]> granicus.if.org Git - strace/blob - strace.c
2006-12-12 Dmitry V. Levin <ldv@altlinux.org>
[strace] / strace.c
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  *      $Id$
31  */
32
33 #include "defs.h"
34
35 #include <sys/types.h>
36 #include <signal.h>
37 #include <errno.h>
38 #include <sys/param.h>
39 #include <fcntl.h>
40 #include <sys/resource.h>
41 #include <sys/wait.h>
42 #include <sys/stat.h>
43 #include <pwd.h>
44 #include <grp.h>
45 #include <string.h>
46 #include <limits.h>
47 #include <dirent.h>
48
49 #if defined(IA64) && defined(LINUX)
50 # include <asm/ptrace_offsets.h>
51 #endif
52
53 #ifdef USE_PROCFS
54 #include <poll.h>
55 #endif
56
57 #ifdef SVR4
58 #include <sys/stropts.h>
59 #ifdef HAVE_MP_PROCFS
60 #ifdef HAVE_SYS_UIO_H
61 #include <sys/uio.h>
62 #endif
63 #endif
64 #endif
65
66 int debug = 0, followfork = 0, followvfork = 0;
67 int dtime = 0, cflag = 0, xflag = 0, qflag = 0;
68 static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0;
69
70 /* Sometimes we want to print only succeeding syscalls. */
71 int not_failing_only = 0;
72
73 static char *username = NULL;
74 uid_t run_uid;
75 gid_t run_gid;
76
77 int acolumn = DEFAULT_ACOLUMN;
78 int max_strlen = DEFAULT_STRLEN;
79 static char *outfname = NULL;
80 FILE *outf;
81 struct tcb **tcbtab;
82 unsigned int nprocs, tcbtabsize;
83 char *progname;
84 extern char **environ;
85
86 static int trace P((void));
87 static void cleanup P((void));
88 static void interrupt P((int sig));
89 static sigset_t empty_set, blocked_set;
90
91 #ifdef HAVE_SIG_ATOMIC_T
92 static volatile sig_atomic_t interrupted;
93 #else /* !HAVE_SIG_ATOMIC_T */
94 #ifdef __STDC__
95 static volatile int interrupted;
96 #else /* !__STDC__ */
97 static int interrupted;
98 #endif /* !__STDC__ */
99 #endif /* !HAVE_SIG_ATOMIC_T */
100
101 #ifdef USE_PROCFS
102
103 static struct tcb *pfd2tcb P((int pfd));
104 static void reaper P((int sig));
105 static void rebuild_pollv P((void));
106 static struct pollfd *pollv;
107
108 #ifndef HAVE_POLLABLE_PROCFS
109
110 static void proc_poll_open P((void));
111 static void proc_poller P((int pfd));
112
113 struct proc_pollfd {
114         int fd;
115         int revents;
116         int pid;
117 };
118
119 static int poller_pid;
120 static int proc_poll_pipe[2] = { -1, -1 };
121
122 #endif /* !HAVE_POLLABLE_PROCFS */
123
124 #ifdef HAVE_MP_PROCFS
125 #define POLLWANT        POLLWRNORM
126 #else
127 #define POLLWANT        POLLPRI
128 #endif
129 #endif /* USE_PROCFS */
130
131 static void
132 usage(ofp, exitval)
133 FILE *ofp;
134 int exitval;
135 {
136         fprintf(ofp, "\
137 usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\
138               [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\
139               [command [arg ...]]\n\
140    or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\
141               [command [arg ...]]\n\
142 -c -- count time, calls, and errors for each syscall and report summary\n\
143 -f -- follow forks, -ff -- with output into separate files\n\
144 -F -- attempt to follow vforks, -h -- print help message\n\
145 -i -- print instruction pointer at time of syscall\n\
146 -q -- suppress messages about attaching, detaching, etc.\n\
147 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
148 -T -- print time spent in each syscall, -V -- print version\n\
149 -v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\
150 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
151 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
152 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
153    options: trace, abbrev, verbose, raw, signal, read, or write\n\
154 -o file -- send trace output to FILE instead of stderr\n\
155 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
156 -p pid -- trace process with process id PID, may be repeated\n\
157 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
158 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
159 -u username -- run command as username handling setuid and/or setgid\n\
160 -E var=val -- put var=val in the environment for command\n\
161 -E var -- remove var from the environment for command\n\
162 " /* this is broken, so don't document it
163 -z -- print only succeeding syscalls\n\
164   */
165 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
166         exit(exitval);
167 }
168
169 #ifdef SVR4
170 #ifdef MIPS
171 void
172 foobar()
173 {
174 }
175 #endif /* MIPS */
176 #endif /* SVR4 */
177
178 static int
179 set_cloexec_flag(int fd)
180 {
181         int     flags, newflags;
182
183         if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
184         {
185                 fprintf(stderr, "%s: fcntl F_GETFD: %s\n",
186                         progname, strerror(errno));
187                 return -1;
188         }
189
190         newflags = flags | FD_CLOEXEC;
191         if (flags == newflags)
192                 return 0;
193
194         if (fcntl(fd, F_SETFD, newflags) < 0)
195         {
196                 fprintf(stderr, "%s: fcntl F_SETFD: %s\n",
197                         progname, strerror(errno));
198                 return -1;
199         }
200
201         return 0;
202 }
203
204 /*
205  * When strace is setuid executable, we have to swap uids
206  * before and after filesystem and process management operations.
207  */
208 static void
209 swap_uid(void)
210 {
211 #ifndef SVR4
212         int euid = geteuid(), uid = getuid();
213
214         if (euid != uid && setreuid(euid, uid) < 0)
215         {
216                 fprintf(stderr, "%s: setreuid: %s\n",
217                         progname, strerror(errno));
218                 exit(1);
219         }
220 #endif
221 }
222
223 static FILE *
224 strace_fopen(const char *path, const char *mode)
225 {
226         FILE *fp;
227
228         swap_uid();
229         if ((fp = fopen(path, mode)) == NULL)
230                 fprintf(stderr, "%s: can't fopen '%s': %s\n",
231                         progname, path, strerror(errno));
232         swap_uid();
233         if (fp && set_cloexec_flag(fileno(fp)) < 0)
234         {
235                 fclose(fp);
236                 fp = NULL;
237         }
238         return fp;
239 }
240
241 static int popen_pid = -1;
242
243 #ifndef _PATH_BSHELL
244 # define _PATH_BSHELL "/bin/sh"
245 #endif
246
247 /*
248  * We cannot use standard popen(3) here because we have to distinguish
249  * popen child process from other processes we trace, and standard popen(3)
250  * does not export its child's pid.
251  */
252 static FILE *
253 strace_popen(const char *command)
254 {
255         int     fds[2];
256
257         swap_uid();
258         if (pipe(fds) < 0)
259         {
260                 fprintf(stderr, "%s: pipe: %s\n",
261                         progname, strerror(errno));
262                 swap_uid();
263                 return NULL;
264         }
265
266         if (set_cloexec_flag(fds[1]) < 0)
267         {
268                 close(fds[0]);
269                 close(fds[1]);
270                 swap_uid();
271                 return NULL;
272         }
273
274         if ((popen_pid = fork()) == -1)
275         {
276                 fprintf(stderr, "%s: fork: %s\n",
277                         progname, strerror(errno));
278                 close(fds[0]);
279                 close(fds[1]);
280                 swap_uid();
281                 return NULL;
282         }
283
284         if (popen_pid)
285         {
286                 /* parent */
287                 close(fds[0]);
288                 swap_uid();
289                 return fdopen(fds[1], "w");
290         } else
291         {
292                 /* child */
293                 close(fds[1]);
294                 if (fds[0] && (dup2(fds[0], 0) || close(fds[0])))
295                 {
296                         fprintf(stderr, "%s: dup2: %s\n",
297                                 progname, strerror(errno));
298                         _exit(1);
299                 }
300                 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
301                 fprintf(stderr, "%s: execl: %s: %s\n",
302                         progname, _PATH_BSHELL, strerror(errno));
303                 _exit(1);
304         }
305 }
306
307 static int
308 newoutf(struct tcb *tcp)
309 {
310         if (outfname && followfork > 1) {
311                 char name[MAXPATHLEN];
312                 FILE *fp;
313
314                 sprintf(name, "%s.%u", outfname, tcp->pid);
315                 if ((fp = strace_fopen(name, "w")) == NULL)
316                         return -1;
317                 tcp->outf = fp;
318         }
319         return 0;
320 }
321
322 int
323 main(argc, argv)
324 int argc;
325 char *argv[];
326 {
327         extern int optind;
328         extern char *optarg;
329         struct tcb *tcp;
330         int c, pid = 0;
331         struct sigaction sa;
332
333         static char buf[BUFSIZ];
334
335         /* Allocate the initial tcbtab.  */
336         tcbtabsize = argc;      /* Surely enough for all -p args.  */
337         tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]);
338         tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]);
339         for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp)
340                 tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]];
341
342         progname = argv[0];
343         outf = stderr;
344         interactive = 1;
345         set_sortby(DEFAULT_SORTBY);
346         set_personality(DEFAULT_PERSONALITY);
347         qualify("trace=all");
348         qualify("abbrev=all");
349         qualify("verbose=all");
350         qualify("signal=all");
351         while ((c = getopt(argc, argv,
352                 "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {
353                 switch (c) {
354                 case 'c':
355                         cflag++;
356                         dtime++;
357                         break;
358                 case 'd':
359                         debug++;
360                         break;
361                 case 'f':
362                         followfork++;
363                         break;
364                 case 'F':
365                         followvfork++;
366                         break;
367                 case 'h':
368                         usage(stdout, 0);
369                         break;
370                 case 'i':
371                         iflag++;
372                         break;
373                 case 'q':
374                         qflag++;
375                         break;
376                 case 'r':
377                         rflag++;
378                         tflag++;
379                         break;
380                 case 't':
381                         tflag++;
382                         break;
383                 case 'T':
384                         dtime++;
385                         break;
386                 case 'x':
387                         xflag++;
388                         break;
389                 case 'v':
390                         qualify("abbrev=none");
391                         break;
392                 case 'V':
393                         printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
394                         exit(0);
395                         break;
396                 case 'z':
397                         not_failing_only = 1;
398                         break;
399                 case 'a':
400                         acolumn = atoi(optarg);
401                         break;
402                 case 'e':
403                         qualify(optarg);
404                         break;
405                 case 'o':
406                         outfname = strdup(optarg);
407                         break;
408                 case 'O':
409                         set_overhead(atoi(optarg));
410                         break;
411                 case 'p':
412                         if ((pid = atoi(optarg)) <= 0) {
413                                 fprintf(stderr, "%s: Invalid process id: %s\n",
414                                         progname, optarg);
415                                 break;
416                         }
417                         if (pid == getpid()) {
418                                 fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname);
419                                 break;
420                         }
421                         if ((tcp = alloc_tcb(pid, 0)) == NULL) {
422                                 fprintf(stderr, "%s: out of memory\n",
423                                         progname);
424                                 exit(1);
425                         }
426                         tcp->flags |= TCB_ATTACHED;
427                         pflag_seen++;
428                         break;
429                 case 's':
430                         max_strlen = atoi(optarg);
431                         if (max_strlen < 0) {
432                                 fprintf(stderr,
433                                         "%s: invalid -s argument: %s\n",
434                                         progname, optarg);
435                                 exit(1);
436                         }
437                         break;
438                 case 'S':
439                         set_sortby(optarg);
440                         break;
441                 case 'u':
442                         username = strdup(optarg);
443                         break;
444                 case 'E':
445                         if (putenv(optarg) < 0) {
446                                 fprintf(stderr, "%s: out of memory\n",
447                                         progname);
448                                 exit(1);
449                         }
450                         break;
451                 default:
452                         usage(stderr, 1);
453                         break;
454                 }
455         }
456
457         if ((optind == argc) == !pflag_seen)
458                 usage(stderr, 1);
459
460         if (followfork > 1 && cflag) {
461                 fprintf(stderr,
462                         "%s: -c and -ff are mutually exclusive options\n",
463                         progname);
464                 exit(1);
465         }
466
467         /* See if they want to run as another user. */
468         if (username != NULL) {
469                 struct passwd *pent;
470
471                 if (getuid() != 0 || geteuid() != 0) {
472                         fprintf(stderr,
473                                 "%s: you must be root to use the -u option\n",
474                                 progname);
475                         exit(1);
476                 }
477                 if ((pent = getpwnam(username)) == NULL) {
478                         fprintf(stderr, "%s: cannot find user `%s'\n",
479                                 progname, optarg);
480                         exit(1);
481                 }
482                 run_uid = pent->pw_uid;
483                 run_gid = pent->pw_gid;
484         }
485         else {
486                 run_uid = getuid();
487                 run_gid = getgid();
488         }
489
490         /* Check if they want to redirect the output. */
491         if (outfname) {
492                 /* See if they want to pipe the output. */
493                 if (outfname[0] == '|' || outfname[0] == '!') {
494                         /*
495                          * We can't do the <outfname>.PID funny business
496                          * when using popen, so prohibit it.
497                          */
498                         if (followfork > 1) {
499                                 fprintf(stderr, "\
500 %s: piping the output and -ff are mutually exclusive options\n",
501                                         progname);
502                                 exit(1);
503                         }
504
505                         if ((outf = strace_popen(outfname + 1)) == NULL)
506                                 exit(1);
507                 }
508                 else if (followfork <= 1 &&
509                          (outf = strace_fopen(outfname, "w")) == NULL)
510                         exit(1);
511         }
512
513         if (!outfname || outfname[0] == '|' || outfname[0] == '!')
514                 setvbuf(outf, buf, _IOLBF, BUFSIZ);
515         if (outfname && optind < argc) {
516                 interactive = 0;
517                 qflag = 1;
518         }
519
520         for (c = 0; c < tcbtabsize; c++) {
521                 tcp = tcbtab[c];
522                 if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
523                         continue;
524 #ifdef LINUX
525                 if (tcp->flags & TCB_CLONE_THREAD)
526                         continue;
527 #endif
528                 /* Reinitialize the output since it may have changed. */
529                 tcp->outf = outf;
530                 if (newoutf(tcp) < 0)
531                         exit(1);
532
533 #ifdef USE_PROCFS
534                 if (proc_open(tcp, 1) < 0) {
535                         fprintf(stderr, "trouble opening proc file\n");
536                         droptcb(tcp);
537                         continue;
538                 }
539 #else /* !USE_PROCFS */
540 # ifdef LINUX
541                 if (followfork) {
542                         char procdir[MAXPATHLEN];
543                         DIR *dir;
544
545                         sprintf(procdir, "/proc/%d/task", tcp->pid);
546                         dir = opendir(procdir);
547                         if (dir != NULL) {
548                                 unsigned int ntid = 0, nerr = 0;
549                                 struct dirent *de;
550                                 int tid;
551                                 while ((de = readdir(dir)) != NULL) {
552                                         if (de->d_fileno == 0 ||
553                                             de->d_name[0] == '.')
554                                                 continue;
555                                         tid = atoi(de->d_name);
556                                         if (tid <= 0)
557                                                 continue;
558                                         ++ntid;
559                                         if (ptrace(PTRACE_ATTACH, tid,
560                                                    (char *) 1, 0) < 0)
561                                                 ++nerr;
562                                         else if (tid != tcbtab[c]->pid) {
563                                                 if (nprocs == tcbtabsize &&
564                                                     expand_tcbtab())
565                                                         tcp = NULL;
566                                                 else
567                                                         tcp = alloctcb(tid);
568                                                 if (tcp == NULL)
569                                                         exit(1);
570                                                 tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_CLONE_DETACHED|TCB_FOLLOWFORK;
571                                                 tcbtab[c]->nchildren++;
572                                                 tcbtab[c]->nclone_threads++;
573                                                 tcbtab[c]->nclone_detached++;
574                                                 tcp->parent = tcbtab[c];
575                                         }
576                                 }
577                                 closedir(dir);
578                                 if (nerr == ntid) {
579                                         perror("attach: ptrace(PTRACE_ATTACH, ...)");
580                                         droptcb(tcp);
581                                         continue;
582                                 }
583                                 if (!qflag) {
584                                         ntid -= nerr;
585                                         if (ntid > 1)
586                                                 fprintf(stderr, "\
587 Process %u attached with %u threads - interrupt to quit\n",
588                                                         tcp->pid, ntid);
589                                         else
590                                                 fprintf(stderr, "\
591 Process %u attached - interrupt to quit\n",
592                                                         tcp->pid);
593                                 }
594                                 continue;
595                         }
596                 }
597 # endif
598                 if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
599                         perror("attach: ptrace(PTRACE_ATTACH, ...)");
600                         droptcb(tcp);
601                         continue;
602                 }
603 #endif /* !USE_PROCFS */
604                 if (!qflag)
605                         fprintf(stderr,
606                                 "Process %u attached - interrupt to quit\n",
607                                 tcp->pid);
608         }
609
610         if (!pflag_seen) {
611                 struct stat statbuf;
612                 char *filename;
613                 char pathname[MAXPATHLEN];
614
615                 filename = argv[optind];
616                 if (strchr(filename, '/')) {
617                         if (strlen(filename) > sizeof pathname - 1) {
618                                 errno = ENAMETOOLONG;
619                                 perror("strace: exec");
620                                 exit(1);
621                         }
622                         strcpy(pathname, filename);
623                 }
624 #ifdef USE_DEBUGGING_EXEC
625                 /*
626                  * Debuggers customarily check the current directory
627                  * first regardless of the path but doing that gives
628                  * security geeks a panic attack.
629                  */
630                 else if (stat(filename, &statbuf) == 0)
631                         strcpy(pathname, filename);
632 #endif /* USE_DEBUGGING_EXEC */
633                 else {
634                         char *path;
635                         int m, n, len;
636
637                         for (path = getenv("PATH"); path && *path; path += m) {
638                                 if (strchr(path, ':')) {
639                                         n = strchr(path, ':') - path;
640                                         m = n + 1;
641                                 }
642                                 else
643                                         m = n = strlen(path);
644                                 if (n == 0) {
645                                         if (!getcwd(pathname, MAXPATHLEN))
646                                                 continue;
647                                         len = strlen(pathname);
648                                 }
649                                 else if (n > sizeof pathname - 1)
650                                         continue;
651                                 else {
652                                         strncpy(pathname, path, n);
653                                         len = n;
654                                 }
655                                 if (len && pathname[len - 1] != '/')
656                                         pathname[len++] = '/';
657                                 strcpy(pathname + len, filename);
658                                 if (stat(pathname, &statbuf) == 0 &&
659                                     /* Accept only regular files
660                                        with some execute bits set.
661                                        XXX not perfect, might still fail */
662                                     S_ISREG(statbuf.st_mode) &&
663                                     (statbuf.st_mode & 0111))
664                                         break;
665                         }
666                 }
667                 if (stat(pathname, &statbuf) < 0) {
668                         fprintf(stderr, "%s: %s: command not found\n",
669                                 progname, filename);
670                         exit(1);
671                 }
672                 switch (pid = fork()) {
673                 case -1:
674                         perror("strace: fork");
675                         cleanup();
676                         exit(1);
677                         break;
678                 case 0: {
679 #ifdef USE_PROCFS
680                         if (outf != stderr) close (fileno (outf));
681 #ifdef MIPS
682                         /* Kludge for SGI, see proc_open for details. */
683                         sa.sa_handler = foobar;
684                         sa.sa_flags = 0;
685                         sigemptyset(&sa.sa_mask);
686                         sigaction(SIGINT, &sa, NULL);
687 #endif /* MIPS */
688 #ifndef FREEBSD
689                         pause();
690 #else /* FREEBSD */
691                         kill(getpid(), SIGSTOP); /* stop HERE */
692 #endif /* FREEBSD */
693 #else /* !USE_PROCFS */
694                         if (outf!=stderr)
695                                 close(fileno (outf));
696
697                         if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) {
698                                 perror("strace: ptrace(PTRACE_TRACEME, ...)");
699                                 return -1;
700                         }
701                         if (debug)
702                                 kill(getpid(), SIGSTOP);
703
704                         if (username != NULL || geteuid() == 0) {
705                                 uid_t run_euid = run_uid;
706                                 gid_t run_egid = run_gid;
707
708                                 if (statbuf.st_mode & S_ISUID)
709                                         run_euid = statbuf.st_uid;
710                                 if (statbuf.st_mode & S_ISGID)
711                                         run_egid = statbuf.st_gid;
712
713                                 /*
714                                  * It is important to set groups before we
715                                  * lose privileges on setuid.
716                                  */
717                                 if (username != NULL) {
718                                         if (initgroups(username, run_gid) < 0) {
719                                                 perror("initgroups");
720                                                 exit(1);
721                                         }
722                                         if (setregid(run_gid, run_egid) < 0) {
723                                                 perror("setregid");
724                                                 exit(1);
725                                         }
726                                         if (setreuid(run_uid, run_euid) < 0) {
727                                                 perror("setreuid");
728                                                 exit(1);
729                                         }
730                                 }
731                         }
732                         else
733                                 setreuid(run_uid, run_uid);
734
735                         /*
736                          * Induce an immediate stop so that the parent
737                          * will resume us with PTRACE_SYSCALL and display
738                          * this execve call normally.
739                          */
740                         kill(getpid(), SIGSTOP);
741 #endif /* !USE_PROCFS */
742
743                         execv(pathname, &argv[optind]);
744                         perror("strace: exec");
745                         _exit(1);
746                         break;
747                 }
748                 default:
749                         if ((tcp = alloctcb(pid)) == NULL) {
750                                 cleanup();
751                                 exit(1);
752                         }
753 #ifdef USE_PROCFS
754                         if (proc_open(tcp, 0) < 0) {
755                                 fprintf(stderr, "trouble opening proc file\n");
756                                 cleanup();
757                                 exit(1);
758                         }
759 #endif /* USE_PROCFS */
760                         break;
761                 }
762         }
763
764         sigemptyset(&empty_set);
765         sigemptyset(&blocked_set);
766         sa.sa_handler = SIG_IGN;
767         sigemptyset(&sa.sa_mask);
768         sa.sa_flags = 0;
769         sigaction(SIGTTOU, &sa, NULL);
770         sigaction(SIGTTIN, &sa, NULL);
771         if (interactive) {
772                 sigaddset(&blocked_set, SIGHUP);
773                 sigaddset(&blocked_set, SIGINT);
774                 sigaddset(&blocked_set, SIGQUIT);
775                 sigaddset(&blocked_set, SIGPIPE);
776                 sigaddset(&blocked_set, SIGTERM);
777                 sa.sa_handler = interrupt;
778 #ifdef SUNOS4
779                 /* POSIX signals on sunos4.1 are a little broken. */
780                 sa.sa_flags = SA_INTERRUPT;
781 #endif /* SUNOS4 */
782         }
783         sigaction(SIGHUP, &sa, NULL);
784         sigaction(SIGINT, &sa, NULL);
785         sigaction(SIGQUIT, &sa, NULL);
786         sigaction(SIGPIPE, &sa, NULL);
787         sigaction(SIGTERM, &sa, NULL);
788 #ifdef USE_PROCFS
789         sa.sa_handler = reaper;
790         sigaction(SIGCHLD, &sa, NULL);
791 #else
792         /* Make sure SIGCHLD has the default action so that waitpid
793            definitely works without losing track of children.  The user
794            should not have given us a bogus state to inherit, but he might
795            have.  Arguably we should detect SIG_IGN here and pass it on
796            to children, but probably noone really needs that.  */
797         sa.sa_handler = SIG_DFL;
798         sigaction(SIGCHLD, &sa, NULL);
799 #endif /* USE_PROCFS */
800
801         if (trace() < 0)
802                 exit(1);
803         cleanup();
804         exit(0);
805 }
806
807 int
808 expand_tcbtab()
809 {
810         /* Allocate some more TCBs and expand the table.
811            We don't want to relocate the TCBs because our
812            callers have pointers and it would be a pain.
813            So tcbtab is a table of pointers.  Since we never
814            free the TCBs, we allocate a single chunk of many.  */
815         struct tcb **newtab = (struct tcb **)
816                 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
817         struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
818                                                     sizeof *newtcbs);
819         int i;
820         if (newtab == NULL || newtcbs == NULL) {
821                 if (newtab != NULL)
822                         free(newtab);
823                 fprintf(stderr, "%s: expand_tcbtab: out of memory\n",
824                         progname);
825                 return 1;
826         }
827         for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
828                 newtab[i] = &newtcbs[i - tcbtabsize];
829         tcbtabsize *= 2;
830         tcbtab = newtab;
831
832         return 0;
833 }
834
835
836 struct tcb *
837 alloc_tcb(int pid, int command_options_parsed)
838 {
839         int i;
840         struct tcb *tcp;
841
842         for (i = 0; i < tcbtabsize; i++) {
843                 tcp = tcbtab[i];
844                 if ((tcp->flags & TCB_INUSE) == 0) {
845                         tcp->pid = pid;
846                         tcp->parent = NULL;
847                         tcp->nchildren = 0;
848                         tcp->nzombies = 0;
849 #ifdef TCB_CLONE_THREAD
850                         tcp->nclone_threads = tcp->nclone_detached = 0;
851                         tcp->nclone_waiting = 0;
852 #endif
853                         tcp->flags = TCB_INUSE | TCB_STARTUP;
854                         tcp->outf = outf; /* Initialise to current out file */
855                         tcp->stime.tv_sec = 0;
856                         tcp->stime.tv_usec = 0;
857                         tcp->pfd = -1;
858                         nprocs++;
859                         if (command_options_parsed)
860                                 newoutf(tcp);
861                         return tcp;
862                 }
863         }
864         fprintf(stderr, "%s: alloc_tcb: tcb table full\n", progname);
865         return NULL;
866 }
867
868 #ifdef USE_PROCFS
869 int
870 proc_open(tcp, attaching)
871 struct tcb *tcp;
872 int attaching;
873 {
874         char proc[32];
875         long arg;
876 #ifdef SVR4
877         int i;
878         sysset_t syscalls;
879         sigset_t signals;
880         fltset_t faults;
881 #endif
882 #ifndef HAVE_POLLABLE_PROCFS
883         static int last_pfd;
884 #endif
885
886 #ifdef HAVE_MP_PROCFS
887         /* Open the process pseudo-files in /proc. */
888         sprintf(proc, "/proc/%d/ctl", tcp->pid);
889         if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
890                 perror("strace: open(\"/proc/...\", ...)");
891                 return -1;
892         }
893         if (set_cloexec_flag(tcp->pfd) < 0) {
894                 return -1;
895         }
896         sprintf(proc, "/proc/%d/status", tcp->pid);
897         if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
898                 perror("strace: open(\"/proc/...\", ...)");
899                 return -1;
900         }
901         if (set_cloexec_flag(tcp->pfd_stat) < 0) {
902                 return -1;
903         }
904         sprintf(proc, "/proc/%d/as", tcp->pid);
905         if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
906                 perror("strace: open(\"/proc/...\", ...)");
907                 return -1;
908         }
909         if (set_cloexec_flag(tcp->pfd_as) < 0) {
910                 return -1;
911         }
912 #else
913         /* Open the process pseudo-file in /proc. */
914 #ifndef FREEBSD
915         sprintf(proc, "/proc/%d", tcp->pid);
916         if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
917 #else /* FREEBSD */
918         sprintf(proc, "/proc/%d/mem", tcp->pid);
919         if ((tcp->pfd = open(proc, O_RDWR)) < 0) {
920 #endif /* FREEBSD */
921                 perror("strace: open(\"/proc/...\", ...)");
922                 return -1;
923         }
924         if (set_cloexec_flag(tcp->pfd) < 0) {
925                 return -1;
926         }
927 #endif
928 #ifdef FREEBSD
929         sprintf(proc, "/proc/%d/regs", tcp->pid);
930         if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) {
931                 perror("strace: open(\"/proc/.../regs\", ...)");
932                 return -1;
933         }
934         if (cflag) {
935                 sprintf(proc, "/proc/%d/status", tcp->pid);
936                 if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) {
937                         perror("strace: open(\"/proc/.../status\", ...)");
938                         return -1;
939                 }
940         } else
941                 tcp->pfd_status = -1;
942 #endif /* FREEBSD */
943         rebuild_pollv();
944         if (!attaching) {
945                 /*
946                  * Wait for the child to pause.  Because of a race
947                  * condition we have to poll for the event.
948                  */
949                 for (;;) {
950                         if (IOCTL_STATUS (tcp) < 0) {
951                                 perror("strace: PIOCSTATUS");
952                                 return -1;
953                         }
954                         if (tcp->status.PR_FLAGS & PR_ASLEEP)
955                             break;
956                 }
957         }
958 #ifndef FREEBSD
959         /* Stop the process so that we own the stop. */
960         if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) {
961                 perror("strace: PIOCSTOP");
962                 return -1;
963         }
964 #endif
965 #ifdef PIOCSET
966         /* Set Run-on-Last-Close. */
967         arg = PR_RLC;
968         if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
969                 perror("PIOCSET PR_RLC");
970                 return -1;
971         }
972         /* Set or Reset Inherit-on-Fork. */
973         arg = PR_FORK;
974         if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
975                 perror("PIOC{SET,RESET} PR_FORK");
976                 return -1;
977         }
978 #else  /* !PIOCSET */
979 #ifndef FREEBSD
980         if (ioctl(tcp->pfd, PIOCSRLC) < 0) {
981                 perror("PIOCSRLC");
982                 return -1;
983         }
984         if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) {
985                 perror("PIOC{S,R}FORK");
986                 return -1;
987         }
988 #else /* FREEBSD */
989         /* just unset the PF_LINGER flag for the Run-on-Last-Close. */
990         if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) {
991                 perror("PIOCGFL");
992                 return -1;
993         }
994         arg &= ~PF_LINGER;
995         if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) {
996                 perror("PIOCSFL");
997                 return -1;
998         }
999 #endif /* FREEBSD */
1000 #endif /* !PIOCSET */
1001 #ifndef FREEBSD
1002         /* Enable all syscall entries we care about. */
1003         premptyset(&syscalls);
1004         for (i = 1; i < MAX_QUALS; ++i) {
1005                 if (i > (sizeof syscalls) * CHAR_BIT) break;
1006                 if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i);
1007         }
1008         praddset (&syscalls, SYS_execve);
1009         if (followfork) {
1010                 praddset (&syscalls, SYS_fork);
1011 #ifdef SYS_forkall
1012                 praddset (&syscalls, SYS_forkall);
1013 #endif
1014 #ifdef SYS_fork1
1015                 praddset (&syscalls, SYS_fork1);
1016 #endif
1017 #ifdef SYS_rfork1
1018                 praddset (&syscalls, SYS_rfork1);
1019 #endif
1020 #ifdef SYS_rforkall
1021                 praddset (&syscalls, SYS_rforkall);
1022 #endif
1023         }
1024         if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) {
1025                 perror("PIOCSENTRY");
1026                 return -1;
1027         }
1028         /* Enable the syscall exits. */
1029         if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) {
1030                 perror("PIOSEXIT");
1031                 return -1;
1032         }
1033         /* Enable signals we care about. */
1034         premptyset(&signals);
1035         for (i = 1; i < MAX_QUALS; ++i) {
1036                 if (i > (sizeof signals) * CHAR_BIT) break;
1037                 if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i);
1038         }
1039         if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
1040                 perror("PIOCSTRACE");
1041                 return -1;
1042         }
1043         /* Enable faults we care about */
1044         premptyset(&faults);
1045         for (i = 1; i < MAX_QUALS; ++i) {
1046                 if (i > (sizeof faults) * CHAR_BIT) break;
1047                 if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i);
1048         }
1049         if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
1050                 perror("PIOCSFAULT");
1051                 return -1;
1052         }
1053 #else /* FREEBSD */
1054         /* set events flags. */
1055         arg = S_SIG | S_SCE | S_SCX ;
1056         if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) {
1057                 perror("PIOCBIS");
1058                 return -1;
1059         }
1060 #endif /* FREEBSD */
1061         if (!attaching) {
1062 #ifdef MIPS
1063                 /*
1064                  * The SGI PRSABORT doesn't work for pause() so
1065                  * we send it a caught signal to wake it up.
1066                  */
1067                 kill(tcp->pid, SIGINT);
1068 #else /* !MIPS */
1069 #ifdef PRSABORT
1070                 /* The child is in a pause(), abort it. */
1071                 arg = PRSABORT;
1072                 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
1073                         perror("PIOCRUN");
1074                         return -1;
1075                 }
1076 #endif
1077 #endif /* !MIPS*/
1078 #ifdef FREEBSD
1079                 /* wake up the child if it received the SIGSTOP */
1080                 kill(tcp->pid, SIGCONT);
1081 #endif
1082                 for (;;) {
1083                         /* Wait for the child to do something. */
1084                         if (IOCTL_WSTOP (tcp) < 0) {
1085                                 perror("PIOCWSTOP");
1086                                 return -1;
1087                         }
1088                         if (tcp->status.PR_WHY == PR_SYSENTRY) {
1089                                 tcp->flags &= ~TCB_INSYSCALL;
1090                                 get_scno(tcp);
1091                                 if (known_scno(tcp) == SYS_execve)
1092                                         break;
1093                         }
1094                         /* Set it running: maybe execve will be next. */
1095 #ifndef FREEBSD
1096                         arg = 0;
1097                         if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
1098 #else /* FREEBSD */
1099                         if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) {
1100 #endif /* FREEBSD */
1101                                 perror("PIOCRUN");
1102                                 return -1;
1103                         }
1104 #ifdef FREEBSD
1105                         /* handle the case where we "opened" the child before
1106                            it did the kill -STOP */
1107                         if (tcp->status.PR_WHY == PR_SIGNALLED &&
1108                             tcp->status.PR_WHAT == SIGSTOP)
1109                                 kill(tcp->pid, SIGCONT);
1110 #endif
1111                 }
1112 #ifndef FREEBSD
1113         }
1114 #else /* FREEBSD */
1115         } else {
1116                 if (attaching < 2) {
1117                         /* We are attaching to an already running process.
1118                          * Try to figure out the state of the process in syscalls,
1119                          * to handle the first event well.
1120                          * This is done by having a look at the "wchan" property of the
1121                          * process, which tells where it is stopped (if it is). */
1122                         FILE * status;
1123                         char wchan[20]; /* should be enough */
1124
1125                         sprintf(proc, "/proc/%d/status", tcp->pid);
1126                         status = fopen(proc, "r");
1127                         if (status &&
1128                             (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d"
1129                                     "%*d,%*d %*d,%*d %19s", wchan) == 1) &&
1130                             strcmp(wchan, "nochan") && strcmp(wchan, "spread") &&
1131                             strcmp(wchan, "stopevent")) {
1132                                 /* The process is asleep in the middle of a syscall.
1133                                    Fake the syscall entry event */
1134                                 tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP);
1135                                 tcp->status.PR_WHY = PR_SYSENTRY;
1136                                 trace_syscall(tcp);
1137                         }
1138                         if (status)
1139                                 fclose(status);
1140                 } /* otherwise it's a fork being followed */
1141         }
1142 #endif /* FREEBSD */
1143 #ifndef HAVE_POLLABLE_PROCFS
1144         if (proc_poll_pipe[0] != -1)
1145                 proc_poller(tcp->pfd);
1146         else if (nprocs > 1) {
1147                 proc_poll_open();
1148                 proc_poller(last_pfd);
1149                 proc_poller(tcp->pfd);
1150         }
1151         last_pfd = tcp->pfd;
1152 #endif /* !HAVE_POLLABLE_PROCFS */
1153         return 0;
1154 }
1155
1156 #endif /* USE_PROCFS */
1157
1158 struct tcb *
1159 pid2tcb(pid)
1160 int pid;
1161 {
1162         int i;
1163         struct tcb *tcp;
1164
1165         for (i = 0; i < tcbtabsize; i++) {
1166                 tcp = tcbtab[i];
1167                 if (pid && tcp->pid != pid)
1168                         continue;
1169                 if (tcp->flags & TCB_INUSE)
1170                         return tcp;
1171         }
1172         return NULL;
1173 }
1174
1175 #ifdef USE_PROCFS
1176
1177 static struct tcb *
1178 pfd2tcb(pfd)
1179 int pfd;
1180 {
1181         int i;
1182
1183         for (i = 0; i < tcbtabsize; i++) {
1184                 struct tcb *tcp = tcbtab[i];
1185                 if (tcp->pfd != pfd)
1186                         continue;
1187                 if (tcp->flags & TCB_INUSE)
1188                         return tcp;
1189         }
1190         return NULL;
1191 }
1192
1193 #endif /* USE_PROCFS */
1194
1195 void
1196 droptcb(tcp)
1197 struct tcb *tcp;
1198 {
1199         if (tcp->pid == 0)
1200                 return;
1201 #ifdef TCB_CLONE_THREAD
1202         if (tcp->nclone_threads > 0) {
1203                 /* There are other threads left in this process, but this
1204                    is the one whose PID represents the whole process.
1205                    We need to keep this record around as a zombie until
1206                    all the threads die.  */
1207                 tcp->flags |= TCB_EXITING;
1208                 return;
1209         }
1210 #endif
1211         nprocs--;
1212         tcp->pid = 0;
1213
1214         if (tcp->parent != NULL) {
1215                 tcp->parent->nchildren--;
1216 #ifdef TCB_CLONE_THREAD
1217                 if (tcp->flags & TCB_CLONE_DETACHED)
1218                         tcp->parent->nclone_detached--;
1219                 if (tcp->flags & TCB_CLONE_THREAD)
1220                         tcp->parent->nclone_threads--;
1221 #endif
1222 #ifdef TCB_CLONE_DETACHED
1223                 if (!(tcp->flags & TCB_CLONE_DETACHED))
1224 #endif
1225                         tcp->parent->nzombies++;
1226                 tcp->parent = NULL;
1227         }
1228
1229         tcp->flags = 0;
1230         if (tcp->pfd != -1) {
1231                 close(tcp->pfd);
1232                 tcp->pfd = -1;
1233 #ifdef FREEBSD
1234                 if (tcp->pfd_reg != -1) {
1235                         close(tcp->pfd_reg);
1236                         tcp->pfd_reg = -1;
1237                 }
1238                 if (tcp->pfd_status != -1) {
1239                         close(tcp->pfd_status);
1240                         tcp->pfd_status = -1;
1241                 }
1242 #endif /* !FREEBSD */
1243 #ifdef USE_PROCFS
1244                 rebuild_pollv(); /* Note, flags needs to be cleared by now.  */
1245 #endif
1246         }
1247
1248         if (outfname && followfork > 1 && tcp->outf)
1249                 fclose(tcp->outf);
1250
1251         tcp->outf = 0;
1252 }
1253
1254 #ifndef USE_PROCFS
1255
1256 static int
1257 resume(tcp)
1258 struct tcb *tcp;
1259 {
1260         if (tcp == NULL)
1261                 return -1;
1262
1263         if (!(tcp->flags & TCB_SUSPENDED)) {
1264                 fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid);
1265                 return -1;
1266         }
1267         tcp->flags &= ~TCB_SUSPENDED;
1268 #ifdef TCB_CLONE_THREAD
1269         if (tcp->flags & TCB_CLONE_THREAD)
1270                 tcp->parent->nclone_waiting--;
1271 #endif
1272
1273         if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) {
1274                 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
1275                 return -1;
1276         }
1277
1278         if (!qflag)
1279                 fprintf(stderr, "Process %u resumed\n", tcp->pid);
1280         return 0;
1281 }
1282
1283 #endif /* !USE_PROCFS */
1284
1285 /* detach traced process; continue with sig */
1286
1287 static int
1288 detach(tcp, sig)
1289 struct tcb *tcp;
1290 int sig;
1291 {
1292         int error = 0;
1293 #ifdef LINUX
1294         int status, resumed;
1295         struct tcb *zombie = NULL;
1296
1297         /* If the group leader is lingering only because of this other
1298            thread now dying, then detach the leader as well.  */
1299         if ((tcp->flags & TCB_CLONE_THREAD) &&
1300             tcp->parent->nclone_threads == 1 &&
1301             (tcp->parent->flags & TCB_EXITING))
1302                 zombie = tcp->parent;
1303 #endif
1304
1305         if (tcp->flags & TCB_BPTSET)
1306                 sig = SIGKILL;
1307
1308 #ifdef LINUX
1309         /*
1310          * Linux wrongly insists the child be stopped
1311          * before detaching.  Arghh.  We go through hoops
1312          * to make a clean break of things.
1313          */
1314 #if defined(SPARC)
1315 #undef PTRACE_DETACH
1316 #define PTRACE_DETACH PTRACE_SUNDETACH
1317 #endif
1318         if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) {
1319                 /* On a clear day, you can see forever. */
1320         }
1321         else if (errno != ESRCH) {
1322                 /* Shouldn't happen. */
1323                 perror("detach: ptrace(PTRACE_DETACH, ...)");
1324         }
1325         else if (kill(tcp->pid, 0) < 0) {
1326                 if (errno != ESRCH)
1327                         perror("detach: checking sanity");
1328         }
1329         else if (kill(tcp->pid, SIGSTOP) < 0) {
1330                 if (errno != ESRCH)
1331                         perror("detach: stopping child");
1332         }
1333         else {
1334                 for (;;) {
1335 #ifdef __WALL
1336                         if (wait4(tcp->pid, &status, __WALL, NULL) < 0) {
1337                                 if (errno == ECHILD) /* Already gone.  */
1338                                         break;
1339                                 if (errno != EINVAL) {
1340                                         perror("detach: waiting");
1341                                         break;
1342                                 }
1343 #endif /* __WALL */
1344                                 /* No __WALL here.  */
1345                                 if (waitpid(tcp->pid, &status, 0) < 0) {
1346                                         if (errno != ECHILD) {
1347                                                 perror("detach: waiting");
1348                                                 break;
1349                                         }
1350 #ifdef __WCLONE
1351                                         /* If no processes, try clones.  */
1352                                         if (wait4(tcp->pid, &status, __WCLONE,
1353                                                   NULL) < 0) {
1354                                                 if (errno != ECHILD)
1355                                                         perror("detach: waiting");
1356                                                 break;
1357                                         }
1358 #endif /* __WCLONE */
1359                                 }
1360 #ifdef __WALL
1361                         }
1362 #endif
1363                         if (!WIFSTOPPED(status)) {
1364                                 /* Au revoir, mon ami. */
1365                                 break;
1366                         }
1367                         if (WSTOPSIG(status) == SIGSTOP) {
1368                                 if ((error = ptrace(PTRACE_DETACH,
1369                                     tcp->pid, (char *) 1, sig)) < 0) {
1370                                         if (errno != ESRCH)
1371                                                 perror("detach: ptrace(PTRACE_DETACH, ...)");
1372                                         /* I died trying. */
1373                                 }
1374                                 break;
1375                         }
1376                         if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1,
1377                             WSTOPSIG(status) == SIGTRAP ?
1378                             0 : WSTOPSIG(status))) < 0) {
1379                                 if (errno != ESRCH)
1380                                         perror("detach: ptrace(PTRACE_CONT, ...)");
1381                                 break;
1382                         }
1383                 }
1384         }
1385 #endif /* LINUX */
1386
1387 #if defined(SUNOS4)
1388         /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */
1389         if (sig && kill(tcp->pid, sig) < 0)
1390                 perror("detach: kill");
1391         sig = 0;
1392         if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0)
1393                 perror("detach: ptrace(PTRACE_DETACH, ...)");
1394 #endif /* SUNOS4 */
1395
1396 #ifndef USE_PROCFS
1397         resumed = 0;
1398
1399         /* XXX This won't always be quite right (but it never was).
1400            A waiter with argument 0 or < -1 is waiting for any pid in
1401            a particular pgrp, which this child might or might not be
1402            in.  The waiter will only wake up if it's argument is -1
1403            or if it's waiting for tcp->pid's pgrp.  It makes a
1404            difference to wake up a waiter when there might be more
1405            traced children, because it could get a false ECHILD
1406            error.  OTOH, if this was the last child in the pgrp, then
1407            it ought to wake up and get ECHILD.  We would have to
1408            search the system for all pid's in the pgrp to be sure.
1409
1410              && (t->waitpid == -1 ||
1411                  (t->waitpid == 0 && getpgid (tcp->pid) == getpgid (t->pid))
1412                  || (t->waitpid < 0 && t->waitpid == -getpid (t->pid)))
1413         */
1414
1415         if (tcp->parent &&
1416             (tcp->parent->flags & TCB_SUSPENDED) &&
1417             (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) {
1418                 error = resume(tcp->parent);
1419                 ++resumed;
1420         }
1421 #ifdef TCB_CLONE_THREAD
1422         if (tcp->parent && tcp->parent->nclone_waiting > 0) {
1423                 /* Some other threads of our parent are waiting too.  */
1424                 unsigned int i;
1425
1426                 /* Resume all the threads that were waiting for this PID.  */
1427                 for (i = 0; i < tcbtabsize; i++) {
1428                         struct tcb *t = tcbtab[i];
1429                         if (t->parent == tcp->parent && t != tcp
1430                             && ((t->flags & (TCB_CLONE_THREAD|TCB_SUSPENDED))
1431                                 == (TCB_CLONE_THREAD|TCB_SUSPENDED))
1432                             && t->waitpid == tcp->pid) {
1433                                 error |= resume (t);
1434                                 ++resumed;
1435                         }
1436                 }
1437                 if (resumed == 0)
1438                         /* Noone was waiting for this PID in particular,
1439                            so now we might need to resume some wildcarders.  */
1440                         for (i = 0; i < tcbtabsize; i++) {
1441                                 struct tcb *t = tcbtab[i];
1442                                 if (t->parent == tcp->parent && t != tcp
1443                                     && ((t->flags
1444                                          & (TCB_CLONE_THREAD|TCB_SUSPENDED))
1445                                         == (TCB_CLONE_THREAD|TCB_SUSPENDED))
1446                                     && t->waitpid <= 0
1447                                         ) {
1448                                         error |= resume (t);
1449                                         break;
1450                                 }
1451                         }
1452         }
1453 #endif
1454
1455 #endif /* !USE_PROCFS */
1456
1457         if (!qflag)
1458                 fprintf(stderr, "Process %u detached\n", tcp->pid);
1459
1460         droptcb(tcp);
1461
1462 #ifdef LINUX
1463         if (zombie != NULL)
1464                 error = detach(zombie) || error;
1465 #endif
1466
1467         return error;
1468 }
1469
1470 #ifdef USE_PROCFS
1471
1472 static void
1473 reaper(sig)
1474 int sig;
1475 {
1476         int pid;
1477         int status;
1478
1479         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
1480 #if 0
1481                 struct tcb *tcp;
1482
1483                 tcp = pid2tcb(pid);
1484                 if (tcp)
1485                         droptcb(tcp);
1486 #endif
1487         }
1488 }
1489
1490 #endif /* USE_PROCFS */
1491
1492 static void
1493 cleanup()
1494 {
1495         int i;
1496         struct tcb *tcp;
1497
1498         for (i = 0; i < tcbtabsize; i++) {
1499                 tcp = tcbtab[i];
1500                 if (!(tcp->flags & TCB_INUSE))
1501                         continue;
1502                 if (debug)
1503                         fprintf(stderr,
1504                                 "cleanup: looking at pid %u\n", tcp->pid);
1505                 if (tcp_last &&
1506                     (!outfname || followfork < 2 || tcp_last == tcp)) {
1507                         tprintf(" <unfinished ...>\n");
1508                         tcp_last = NULL;
1509                 }
1510                 if (tcp->flags & TCB_ATTACHED)
1511                         detach(tcp, 0);
1512                 else {
1513                         kill(tcp->pid, SIGCONT);
1514                         kill(tcp->pid, SIGTERM);
1515                 }
1516         }
1517         if (cflag)
1518                 call_summary(outf);
1519 }
1520
1521 static void
1522 interrupt(sig)
1523 int sig;
1524 {
1525         interrupted = 1;
1526 }
1527
1528 #ifndef HAVE_STRERROR
1529
1530 #if !HAVE_DECL_SYS_ERRLIST
1531 extern int sys_nerr;
1532 extern char *sys_errlist[];
1533 #endif /* HAVE_DECL_SYS_ERRLIST */
1534
1535 const char *
1536 strerror(errno)
1537 int errno;
1538 {
1539         static char buf[64];
1540
1541         if (errno < 1 || errno >= sys_nerr) {
1542                 sprintf(buf, "Unknown error %d", errno);
1543                 return buf;
1544         }
1545         return sys_errlist[errno];
1546 }
1547
1548 #endif /* HAVE_STERRROR */
1549
1550 #ifndef HAVE_STRSIGNAL
1551
1552 #if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
1553 extern char *sys_siglist[];
1554 #endif
1555 #if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1556 extern char *_sys_siglist[];
1557 #endif
1558
1559 const char *
1560 strsignal(sig)
1561 int sig;
1562 {
1563         static char buf[64];
1564
1565         if (sig < 1 || sig >= NSIG) {
1566                 sprintf(buf, "Unknown signal %d", sig);
1567                 return buf;
1568         }
1569 #ifdef HAVE__SYS_SIGLIST
1570         return _sys_siglist[sig];
1571 #else
1572         return sys_siglist[sig];
1573 #endif
1574 }
1575
1576 #endif /* HAVE_STRSIGNAL */
1577
1578 #ifdef USE_PROCFS
1579
1580 static void
1581 rebuild_pollv()
1582 {
1583         int i, j;
1584
1585         if (pollv != NULL)
1586                 free (pollv);
1587         pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]);
1588         if (pollv == NULL) {
1589                 fprintf(stderr, "%s: out of memory\n", progname);
1590                 exit(1);
1591         }
1592
1593         for (i = j = 0; i < tcbtabsize; i++) {
1594                 struct tcb *tcp = tcbtab[i];
1595                 if (!(tcp->flags & TCB_INUSE))
1596                         continue;
1597                 pollv[j].fd = tcp->pfd;
1598                 pollv[j].events = POLLWANT;
1599                 j++;
1600         }
1601         if (j != nprocs) {
1602                 fprintf(stderr, "strace: proc miscount\n");
1603                 exit(1);
1604         }
1605 }
1606
1607 #ifndef HAVE_POLLABLE_PROCFS
1608
1609 static void
1610 proc_poll_open()
1611 {
1612         int i;
1613
1614         if (pipe(proc_poll_pipe) < 0) {
1615                 perror("pipe");
1616                 exit(1);
1617         }
1618         for (i = 0; i < 2; i++) {
1619                 if (set_cloexec_flag(proc_poll_pipe[i]) < 0) {
1620                         exit(1);
1621                 }
1622         }
1623 }
1624
1625 static int
1626 proc_poll(pollv, nfds, timeout)
1627 struct pollfd *pollv;
1628 int nfds;
1629 int timeout;
1630 {
1631         int i;
1632         int n;
1633         struct proc_pollfd pollinfo;
1634
1635         if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0)
1636                 return n;
1637         if (n != sizeof(struct proc_pollfd)) {
1638                 fprintf(stderr, "panic: short read: %d\n", n);
1639                 exit(1);
1640         }
1641         for (i = 0; i < nprocs; i++) {
1642                 if (pollv[i].fd == pollinfo.fd)
1643                         pollv[i].revents = pollinfo.revents;
1644                 else
1645                         pollv[i].revents = 0;
1646         }
1647         poller_pid = pollinfo.pid;
1648         return 1;
1649 }
1650
1651 static void
1652 wakeup_handler(sig)
1653 int sig;
1654 {
1655 }
1656
1657 static void
1658 proc_poller(pfd)
1659 int pfd;
1660 {
1661         struct proc_pollfd pollinfo;
1662         struct sigaction sa;
1663         sigset_t blocked_set, empty_set;
1664         int i;
1665         int n;
1666         struct rlimit rl;
1667 #ifdef FREEBSD
1668         struct procfs_status pfs;
1669 #endif /* FREEBSD */
1670
1671         switch (fork()) {
1672         case -1:
1673                 perror("fork");
1674                 _exit(0);
1675         case 0:
1676                 break;
1677         default:
1678                 return;
1679         }
1680
1681         sa.sa_handler = interactive ? SIG_DFL : SIG_IGN;
1682         sa.sa_flags = 0;
1683         sigemptyset(&sa.sa_mask);
1684         sigaction(SIGHUP, &sa, NULL);
1685         sigaction(SIGINT, &sa, NULL);
1686         sigaction(SIGQUIT, &sa, NULL);
1687         sigaction(SIGPIPE, &sa, NULL);
1688         sigaction(SIGTERM, &sa, NULL);
1689         sa.sa_handler = wakeup_handler;
1690         sigaction(SIGUSR1, &sa, NULL);
1691         sigemptyset(&blocked_set);
1692         sigaddset(&blocked_set, SIGUSR1);
1693         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1694         sigemptyset(&empty_set);
1695
1696         if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
1697                 perror("getrlimit(RLIMIT_NOFILE, ...)");
1698                 _exit(0);
1699         }
1700         n = rl.rlim_cur;
1701         for (i = 0; i < n; i++) {
1702                 if (i != pfd && i != proc_poll_pipe[1])
1703                         close(i);
1704         }
1705
1706         pollinfo.fd = pfd;
1707         pollinfo.pid = getpid();
1708         for (;;) {
1709 #ifndef FREEBSD
1710                 if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
1711 #else /* FREEBSD */
1712                 if (ioctl(pfd, PIOCWSTOP, &pfs) < 0)
1713 #endif /* FREEBSD */
1714                 {
1715                         switch (errno) {
1716                         case EINTR:
1717                                 continue;
1718                         case EBADF:
1719                                 pollinfo.revents = POLLERR;
1720                                 break;
1721                         case ENOENT:
1722                                 pollinfo.revents = POLLHUP;
1723                                 break;
1724                         default:
1725                                 perror("proc_poller: PIOCWSTOP");
1726                         }
1727                         write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1728                         _exit(0);
1729                 }
1730                 pollinfo.revents = POLLWANT;
1731                 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1732                 sigsuspend(&empty_set);
1733         }
1734 }
1735
1736 #endif /* !HAVE_POLLABLE_PROCFS */
1737
1738 static int
1739 choose_pfd()
1740 {
1741         int i, j;
1742         struct tcb *tcp;
1743
1744         static int last;
1745
1746         if (followfork < 2 &&
1747             last < nprocs && (pollv[last].revents & POLLWANT)) {
1748                 /*
1749                  * The previous process is ready to run again.  We'll
1750                  * let it do so if it is currently in a syscall.  This
1751                  * heuristic improves the readability of the trace.
1752                  */
1753                 tcp = pfd2tcb(pollv[last].fd);
1754                 if (tcp && (tcp->flags & TCB_INSYSCALL))
1755                         return pollv[last].fd;
1756         }
1757
1758         for (i = 0; i < nprocs; i++) {
1759                 /* Let competing children run round robin. */
1760                 j = (i + last + 1) % nprocs;
1761                 if (pollv[j].revents & (POLLHUP | POLLERR)) {
1762                         tcp = pfd2tcb(pollv[j].fd);
1763                         if (!tcp) {
1764                                 fprintf(stderr, "strace: lost proc\n");
1765                                 exit(1);
1766                         }
1767                         droptcb(tcp);
1768                         return -1;
1769                 }
1770                 if (pollv[j].revents & POLLWANT) {
1771                         last = j;
1772                         return pollv[j].fd;
1773                 }
1774         }
1775         fprintf(stderr, "strace: nothing ready\n");
1776         exit(1);
1777 }
1778
1779 static int
1780 trace()
1781 {
1782 #ifdef POLL_HACK
1783         struct tcb *in_syscall = NULL;
1784 #endif
1785         struct tcb *tcp;
1786         int pfd;
1787         int what;
1788         int ioctl_result = 0, ioctl_errno = 0;
1789         long arg;
1790
1791         for (;;) {
1792                 if (interactive)
1793                         sigprocmask(SIG_SETMASK, &empty_set, NULL);
1794
1795                 if (nprocs == 0)
1796                         break;
1797
1798                 switch (nprocs) {
1799                 case 1:
1800 #ifndef HAVE_POLLABLE_PROCFS
1801                         if (proc_poll_pipe[0] == -1) {
1802 #endif
1803                                 tcp = pid2tcb(0);
1804                                 if (!tcp)
1805                                         continue;
1806                                 pfd = tcp->pfd;
1807                                 if (pfd == -1)
1808                                         continue;
1809                                 break;
1810 #ifndef HAVE_POLLABLE_PROCFS
1811                         }
1812                         /* fall through ... */
1813 #endif /* !HAVE_POLLABLE_PROCFS */
1814                 default:
1815 #ifdef HAVE_POLLABLE_PROCFS
1816 #ifdef POLL_HACK
1817                         /* On some systems (e.g. UnixWare) we get too much ugly
1818                            "unfinished..." stuff when multiple proceses are in
1819                            syscalls.  Here's a nasty hack */
1820
1821                         if (in_syscall) {
1822                                 struct pollfd pv;
1823                                 tcp = in_syscall;
1824                                 in_syscall = NULL;
1825                                 pv.fd = tcp->pfd;
1826                                 pv.events = POLLWANT;
1827                                 if ((what = poll (&pv, 1, 1)) < 0) {
1828                                         if (interrupted)
1829                                                 return 0;
1830                                         continue;
1831                                 }
1832                                 else if (what == 1 && pv.revents & POLLWANT) {
1833                                         goto FOUND;
1834                                 }
1835                         }
1836 #endif
1837
1838                         if (poll(pollv, nprocs, INFTIM) < 0) {
1839                                 if (interrupted)
1840                                         return 0;
1841                                 continue;
1842                         }
1843 #else /* !HAVE_POLLABLE_PROCFS */
1844                         if (proc_poll(pollv, nprocs, INFTIM) < 0) {
1845                                 if (interrupted)
1846                                         return 0;
1847                                 continue;
1848                         }
1849 #endif /* !HAVE_POLLABLE_PROCFS */
1850                         pfd = choose_pfd();
1851                         if (pfd == -1)
1852                                 continue;
1853                         break;
1854                 }
1855
1856                 /* Look up `pfd' in our table. */
1857                 if ((tcp = pfd2tcb(pfd)) == NULL) {
1858                         fprintf(stderr, "unknown pfd: %u\n", pfd);
1859                         exit(1);
1860                 }
1861 #ifdef POLL_HACK
1862         FOUND:
1863 #endif
1864                 /* Get the status of the process. */
1865                 if (!interrupted) {
1866 #ifndef FREEBSD
1867                         ioctl_result = IOCTL_WSTOP (tcp);
1868 #else /* FREEBSD */
1869                         /* Thanks to some scheduling mystery, the first poller
1870                            sometimes waits for the already processed end of fork
1871                            event. Doing a non blocking poll here solves the problem. */
1872                         if (proc_poll_pipe[0] != -1)
1873                                 ioctl_result = IOCTL_STATUS (tcp);
1874                         else
1875                                 ioctl_result = IOCTL_WSTOP (tcp);
1876 #endif /* FREEBSD */
1877                         ioctl_errno = errno;
1878 #ifndef HAVE_POLLABLE_PROCFS
1879                         if (proc_poll_pipe[0] != -1) {
1880                                 if (ioctl_result < 0)
1881                                         kill(poller_pid, SIGKILL);
1882                                 else
1883                                         kill(poller_pid, SIGUSR1);
1884                         }
1885 #endif /* !HAVE_POLLABLE_PROCFS */
1886                 }
1887                 if (interrupted)
1888                         return 0;
1889
1890                 if (interactive)
1891                         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1892
1893                 if (ioctl_result < 0) {
1894                         /* Find out what happened if it failed. */
1895                         switch (ioctl_errno) {
1896                         case EINTR:
1897                         case EBADF:
1898                                 continue;
1899 #ifdef FREEBSD
1900                         case ENOTTY:
1901 #endif
1902                         case ENOENT:
1903                                 droptcb(tcp);
1904                                 continue;
1905                         default:
1906                                 perror("PIOCWSTOP");
1907                                 exit(1);
1908                         }
1909                 }
1910
1911 #ifdef FREEBSD
1912                 if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) {
1913                         /* discard first event for a syscall we never entered */
1914                         IOCTL (tcp->pfd, PIOCRUN, 0);
1915                         continue;
1916                 }
1917 #endif
1918
1919                 /* clear the just started flag */
1920                 tcp->flags &= ~TCB_STARTUP;
1921
1922                 /* set current output file */
1923                 outf = tcp->outf;
1924
1925                 if (cflag) {
1926                         struct timeval stime;
1927 #ifdef FREEBSD
1928                         char buf[1024];
1929                         int len;
1930
1931                         if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) {
1932                                 buf[len] = '\0';
1933                                 sscanf(buf,
1934                                        "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld",
1935                                        &stime.tv_sec, &stime.tv_usec);
1936                         } else
1937                                 stime.tv_sec = stime.tv_usec = 0;
1938 #else /* !FREEBSD */
1939                         stime.tv_sec = tcp->status.pr_stime.tv_sec;
1940                         stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000;
1941 #endif /* !FREEBSD */
1942                         tv_sub(&tcp->dtime, &stime, &tcp->stime);
1943                         tcp->stime = stime;
1944                 }
1945                 what = tcp->status.PR_WHAT;
1946                 switch (tcp->status.PR_WHY) {
1947 #ifndef FREEBSD
1948                 case PR_REQUESTED:
1949                         if (tcp->status.PR_FLAGS & PR_ASLEEP) {
1950                                 tcp->status.PR_WHY = PR_SYSENTRY;
1951                                 if (trace_syscall(tcp) < 0) {
1952                                         fprintf(stderr, "syscall trouble\n");
1953                                         exit(1);
1954                                 }
1955                         }
1956                         break;
1957 #endif /* !FREEBSD */
1958                 case PR_SYSENTRY:
1959 #ifdef POLL_HACK
1960                         in_syscall = tcp;
1961 #endif
1962                 case PR_SYSEXIT:
1963                         if (trace_syscall(tcp) < 0) {
1964                                 fprintf(stderr, "syscall trouble\n");
1965                                 exit(1);
1966                         }
1967                         break;
1968                 case PR_SIGNALLED:
1969                         if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) {
1970                                 printleader(tcp);
1971                                 tprintf("--- %s (%s) ---",
1972                                         signame(what), strsignal(what));
1973                                 printtrailer(tcp);
1974 #ifdef PR_INFO
1975                                 if (tcp->status.PR_INFO.si_signo == what) {
1976                                         printleader(tcp);
1977                                         tprintf("    siginfo=");
1978                                         printsiginfo(&tcp->status.PR_INFO, 1);
1979                                         printtrailer(tcp);
1980                                 }
1981 #endif
1982                         }
1983                         break;
1984                 case PR_FAULTED:
1985                         if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
1986                                 printleader(tcp);
1987                                 tprintf("=== FAULT %d ===", what);
1988                                 printtrailer(tcp);
1989                         }
1990                         break;
1991 #ifdef FREEBSD
1992                 case 0: /* handle case we polled for nothing */
1993                         continue;
1994 #endif
1995                 default:
1996                         fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
1997                         exit(1);
1998                         break;
1999                 }
2000                 arg = 0;
2001 #ifndef FREEBSD
2002                 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
2003 #else
2004                 if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) {
2005 #endif
2006                         perror("PIOCRUN");
2007                         exit(1);
2008                 }
2009         }
2010         return 0;
2011 }
2012
2013 #else /* !USE_PROCFS */
2014
2015 #ifdef TCB_GROUP_EXITING
2016 /* Handle an exit detach or death signal that is taking all the
2017    related clone threads with it.  This is called in three circumstances:
2018    SIG == -1    TCP has already died (TCB_ATTACHED is clear, strace is parent).
2019    SIG == 0     Continuing TCP will perform an exit_group syscall.
2020    SIG == other Continuing TCP with SIG will kill the process.
2021 */
2022 static int
2023 handle_group_exit(struct tcb *tcp, int sig)
2024 {
2025         /* We need to locate our records of all the clone threads
2026            related to TCP, either its children or siblings.  */
2027         struct tcb *leader = ((tcp->flags & TCB_CLONE_THREAD)
2028                               ? tcp->parent
2029                               : tcp->nclone_detached > 0
2030                               ? tcp : NULL);
2031
2032         if (sig < 0) {
2033                 if (leader != NULL && leader != tcp &&
2034                     !(leader->flags & TCB_GROUP_EXITING))
2035                         fprintf(stderr,
2036                                 "PANIC: handle_group_exit: %d leader %d\n",
2037                                 tcp->pid, leader ? leader->pid : -1);
2038                 detach(tcp);    /* Already died.  */
2039         }
2040         else {
2041                 /* Mark that we are taking the process down.  */
2042                 tcp->flags |= TCB_EXITING | TCB_GROUP_EXITING;
2043                 if (tcp->flags & TCB_ATTACHED) {
2044                         if (leader != NULL && leader != tcp) {
2045                                 if (leader->flags & TCB_ATTACHED) {
2046                                         /* We need to detach the leader so
2047                                            that the process death will be
2048                                            reported to its real parent.
2049                                            But we kill it first to prevent
2050                                            it doing anything before we kill
2051                                            the whole process in a moment.
2052                                            We can use PTRACE_KILL on a
2053                                            thread that's not already
2054                                            stopped.  Then the value we pass
2055                                            in PTRACE_DETACH just sets the
2056                                            death signal reported to the
2057                                            real parent.  */
2058                                         ptrace(PTRACE_KILL, leader->pid, 0, 0);
2059                                         if (debug)
2060                                                 fprintf(stderr,
2061                                                         " [%d exit %d kills %d]\n",
2062                                                         tcp->pid, sig, leader->pid);
2063                                         detach(leader, sig);
2064                                 }
2065                                 else
2066                                         leader->flags |= TCB_GROUP_EXITING;
2067                         }
2068                         detach(tcp, sig);
2069                 }
2070                 else if (ptrace(PTRACE_CONT, tcp->pid, (char *) 1, sig) < 0) {
2071                         perror("strace: ptrace(PTRACE_CONT, ...)");
2072                         cleanup();
2073                         return -1;
2074                 }
2075                 else {
2076                         if (leader != NULL)
2077                                 leader->flags |= TCB_GROUP_EXITING;
2078                         if (leader != NULL && leader != tcp)
2079                                 droptcb(tcp);
2080                         /* The leader will report to us as parent now,
2081                            and then we'll get to the SIG==-1 case.  */
2082                         return 0;
2083                 }
2084         }
2085
2086         return 0;
2087 }
2088 #endif
2089
2090 static int
2091 trace()
2092 {
2093         int pid;
2094         int wait_errno;
2095         int status;
2096         struct tcb *tcp;
2097 #ifdef LINUX
2098         struct rusage ru;
2099 #ifdef __WALL
2100         static int wait4_options = __WALL;
2101 #endif
2102 #endif /* LINUX */
2103
2104         while (nprocs != 0) {
2105                 if (interactive)
2106                         sigprocmask(SIG_SETMASK, &empty_set, NULL);
2107 #ifdef LINUX
2108 #ifdef __WALL
2109                 pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL);
2110                 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
2111                         /* this kernel does not support __WALL */
2112                         wait4_options &= ~__WALL;
2113                         errno = 0;
2114                         pid = wait4(-1, &status, wait4_options,
2115                                         cflag ? &ru : NULL);
2116                 }
2117                 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
2118                         /* most likely a "cloned" process */
2119                         pid = wait4(-1, &status, __WCLONE,
2120                                         cflag ? &ru : NULL);
2121                         if (pid == -1) {
2122                                 fprintf(stderr, "strace: clone wait4 "
2123                                                 "failed: %s\n", strerror(errno));
2124                         }
2125                 }
2126 #else
2127                 pid = wait4(-1, &status, 0, cflag ? &ru : NULL);
2128 #endif /* __WALL */
2129 #endif /* LINUX */
2130 #ifdef SUNOS4
2131                 pid = wait(&status);
2132 #endif /* SUNOS4 */
2133                 wait_errno = errno;
2134                 if (interactive)
2135                         sigprocmask(SIG_BLOCK, &blocked_set, NULL);
2136
2137                 if (interrupted)
2138                         return 0;
2139
2140                 if (pid == -1) {
2141                         switch (wait_errno) {
2142                         case EINTR:
2143                                 continue;
2144                         case ECHILD:
2145                                 /*
2146                                  * We would like to verify this case
2147                                  * but sometimes a race in Solbourne's
2148                                  * version of SunOS sometimes reports
2149                                  * ECHILD before sending us SIGCHILD.
2150                                  */
2151 #if 0
2152                                 if (nprocs == 0)
2153                                         return 0;
2154                                 fprintf(stderr, "strace: proc miscount\n");
2155                                 exit(1);
2156 #endif
2157                                 return 0;
2158                         default:
2159                                 errno = wait_errno;
2160                                 perror("strace: wait");
2161                                 return -1;
2162                         }
2163                 }
2164                 if (pid == popen_pid) {
2165                         if (WIFEXITED(status) || WIFSIGNALED(status))
2166                                 popen_pid = -1;
2167                         continue;
2168                 }
2169                 if (debug)
2170                         fprintf(stderr, " [wait(%#x) = %u]\n", status, pid);
2171
2172                 /* Look up `pid' in our table. */
2173                 if ((tcp = pid2tcb(pid)) == NULL) {
2174 #ifdef LINUX
2175                         if (followfork || followvfork) {
2176                                 /* This is needed to go with the CLONE_PTRACE
2177                                    changes in process.c/util.c: we might see
2178                                    the child's initial trap before we see the
2179                                    parent return from the clone syscall.
2180                                    Leave the child suspended until the parent
2181                                    returns from its system call.  Only then
2182                                    will we have the association of parent and
2183                                    child so that we know how to do clearbpt
2184                                    in the child.  */
2185                                 if (nprocs == tcbtabsize &&
2186                                     expand_tcbtab())
2187                                         tcp = NULL;
2188                                 else
2189                                         tcp = alloctcb(pid);
2190                                 if (tcp == NULL) {
2191                                         kill(pid, SIGKILL); /* XXX */
2192                                         return 0;
2193                                 }
2194                                 tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED;
2195                                 if (!qflag)
2196                                         fprintf(stderr, "\
2197 Process %d attached (waiting for parent)\n",
2198                                                 pid);
2199                         }
2200                         else
2201                                 /* This can happen if a clone call used
2202                                    CLONE_PTRACE itself.  */
2203 #endif
2204                         {
2205                                 fprintf(stderr, "unknown pid: %u\n", pid);
2206                                 if (WIFSTOPPED(status))
2207                                         ptrace(PTRACE_CONT, pid, (char *) 1, 0);
2208                                 exit(1);
2209                         }
2210                 }
2211                 /* set current output file */
2212                 outf = tcp->outf;
2213                 if (cflag) {
2214 #ifdef LINUX
2215                         tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2216                         tcp->stime = ru.ru_stime;
2217 #endif /* !LINUX */
2218                 }
2219
2220                 if (tcp->flags & TCB_SUSPENDED) {
2221                         /*
2222                          * Apparently, doing any ptrace() call on a stopped
2223                          * process, provokes the kernel to report the process
2224                          * status again on a subsequent wait(), even if the
2225                          * process has not been actually restarted.
2226                          * Since we have inspected the arguments of suspended
2227                          * processes we end up here testing for this case.
2228                          */
2229                         continue;
2230                 }
2231                 if (WIFSIGNALED(status)) {
2232                         if (!cflag
2233                             && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2234                                 printleader(tcp);
2235                                 tprintf("+++ killed by %s %s+++",
2236                                         signame(WTERMSIG(status)),
2237 #ifdef WCOREDUMP
2238                                         WCOREDUMP(status) ? "(core dumped) " :
2239 #endif
2240                                         "");
2241                                 printtrailer(tcp);
2242                         }
2243 #ifdef TCB_GROUP_EXITING
2244                         handle_group_exit(tcp, -1);
2245 #else
2246                         droptcb(tcp);
2247 #endif
2248                         continue;
2249                 }
2250                 if (WIFEXITED(status)) {
2251                         if (debug)
2252                                 fprintf(stderr, "pid %u exited\n", pid);
2253                         if ((tcp->flags & TCB_ATTACHED)
2254 #ifdef TCB_GROUP_EXITING
2255                             && !(tcp->parent && (tcp->parent->flags &
2256                                                  TCB_GROUP_EXITING))
2257 #endif
2258                                 )
2259                                 fprintf(stderr,
2260                                         "PANIC: attached pid %u exited\n",
2261                                         pid);
2262                         if (tcp == tcp_last) {
2263                                 if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT))
2264                                     == TCB_INSYSCALL)
2265                                         tprintf(" <unfinished ... exit status %d>\n",
2266                                                 WEXITSTATUS(status));
2267                                 tcp_last = NULL;
2268                         }
2269 #ifdef TCB_GROUP_EXITING
2270                         handle_group_exit(tcp, -1);
2271 #else
2272                         droptcb(tcp);
2273 #endif
2274                         continue;
2275                 }
2276                 if (!WIFSTOPPED(status)) {
2277                         fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2278                         droptcb(tcp);
2279                         continue;
2280                 }
2281                 if (debug)
2282                         fprintf(stderr, "pid %u stopped, [%s]\n",
2283                                 pid, signame(WSTOPSIG(status)));
2284
2285                 if (tcp->flags & TCB_STARTUP) {
2286                         /*
2287                          * This flag is there to keep us in sync.
2288                          * Next time this process stops it should
2289                          * really be entering a system call.
2290                          */
2291                         tcp->flags &= ~TCB_STARTUP;
2292                         if (tcp->flags & TCB_ATTACHED) {
2293                                 /*
2294                                  * Interestingly, the process may stop
2295                                  * with STOPSIG equal to some other signal
2296                                  * than SIGSTOP if we happend to attach
2297                                  * just before the process takes a signal.
2298                                  */
2299                                 if (!WIFSTOPPED(status)) {
2300                                         fprintf(stderr,
2301                                                 "pid %u not stopped\n", pid);
2302                                         detach(tcp, WSTOPSIG(status));
2303                                         continue;
2304                                 }
2305                         }
2306                         else {
2307 #ifdef SUNOS4
2308                                 /* A child of us stopped at exec */
2309                                 if (WSTOPSIG(status) == SIGTRAP && followvfork)
2310                                         fixvfork(tcp);
2311 #endif /* SUNOS4 */
2312                         }
2313                         if (tcp->flags & TCB_BPTSET) {
2314                                 if (clearbpt(tcp) < 0) /* Pretty fatal */ {
2315                                         droptcb(tcp);
2316                                         cleanup();
2317                                         return -1;
2318                                 }
2319                         }
2320                         goto tracing;
2321                 }
2322
2323                 if (WSTOPSIG(status) != SIGTRAP) {
2324                         if (WSTOPSIG(status) == SIGSTOP &&
2325                                         (tcp->flags & TCB_SIGTRAPPED)) {
2326                                 /*
2327                                  * Trapped attempt to block SIGTRAP
2328                                  * Hope we are back in control now.
2329                                  */
2330                                 tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED);
2331                                 if (ptrace(PTRACE_SYSCALL,
2332                                                 pid, (char *) 1, 0) < 0) {
2333                                         perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2334                                         cleanup();
2335                                         return -1;
2336                                 }
2337                                 continue;
2338                         }
2339                         if (!cflag
2340                             && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
2341                                 unsigned long addr = 0, pc = 0;
2342 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP) && defined(PT_GETSIGINFO)
2343 #                               define PSR_RI   41
2344                                 struct siginfo si;
2345                                 unsigned long psr;
2346
2347                                 upeek(pid, PT_CR_IPSR, &psr);
2348                                 upeek(pid, PT_CR_IIP, &pc);
2349
2350                                 pc += (psr >> PSR_RI) & 0x3;
2351                                 ptrace(PT_GETSIGINFO, pid, 0, (long) &si);
2352                                 addr = (unsigned long) si.si_addr;
2353 #elif defined PTRACE_GETSIGINFO
2354                                 if (WSTOPSIG(status) == SIGSEGV ||
2355                                     WSTOPSIG(status) == SIGBUS) {
2356                                         siginfo_t si;
2357                                         if (ptrace(PTRACE_GETSIGINFO, pid,
2358                                                    0, &si) == 0)
2359                                                 addr = (unsigned long)
2360                                                         si.si_addr;
2361                                 }
2362 #endif
2363                                 printleader(tcp);
2364                                 tprintf("--- %s (%s) @ %lx (%lx) ---",
2365                                         signame(WSTOPSIG(status)),
2366                                         strsignal(WSTOPSIG(status)), pc, addr);
2367                                 printtrailer(tcp);
2368                         }
2369                         if (((tcp->flags & TCB_ATTACHED) ||
2370                              tcp->nclone_threads > 0) &&
2371                                 !sigishandled(tcp, WSTOPSIG(status))) {
2372 #ifdef TCB_GROUP_EXITING
2373                                 handle_group_exit(tcp, WSTOPSIG(status));
2374 #else
2375                                 detach(tcp, WSTOPSIG(status));
2376 #endif
2377                                 continue;
2378                         }
2379                         if (ptrace(PTRACE_SYSCALL, pid, (char *) 1,
2380                                    WSTOPSIG(status)) < 0) {
2381                                 perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2382                                 cleanup();
2383                                 return -1;
2384                         }
2385                         tcp->flags &= ~TCB_SUSPENDED;
2386                         continue;
2387                 }
2388                 if (trace_syscall(tcp) < 0) {
2389                         if (tcp->flags & TCB_ATTACHED)
2390                                 detach(tcp, 0);
2391                         else {
2392                                 ptrace(PTRACE_KILL,
2393                                         tcp->pid, (char *) 1, SIGTERM);
2394                                 droptcb(tcp);
2395                         }
2396                         continue;
2397                 }
2398                 if (tcp->flags & TCB_EXITING) {
2399 #ifdef TCB_GROUP_EXITING
2400                         if (tcp->flags & TCB_GROUP_EXITING) {
2401                                 if (handle_group_exit(tcp, 0) < 0)
2402                                         return -1;
2403                                 continue;
2404                         }
2405 #endif
2406                         if (tcp->flags & TCB_ATTACHED)
2407                                 detach(tcp, 0);
2408                         else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) {
2409                                 perror("strace: ptrace(PTRACE_CONT, ...)");
2410                                 cleanup();
2411                                 return -1;
2412                         }
2413                         continue;
2414                 }
2415                 if (tcp->flags & TCB_SUSPENDED) {
2416                         if (!qflag)
2417                                 fprintf(stderr, "Process %u suspended\n", pid);
2418                         continue;
2419                 }
2420         tracing:
2421                 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
2422                         perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2423                         cleanup();
2424                         return -1;
2425                 }
2426         }
2427         return 0;
2428 }
2429
2430 #endif /* !USE_PROCFS */
2431
2432 static int curcol;
2433
2434 #ifdef __STDC__
2435 #include <stdarg.h>
2436 #define VA_START(a, b) va_start(a, b)
2437 #else
2438 #include <varargs.h>
2439 #define VA_START(a, b) va_start(a)
2440 #endif
2441
2442 void
2443 #ifdef __STDC__
2444 tprintf(const char *fmt, ...)
2445 #else
2446 tprintf(fmt, va_alist)
2447 char *fmt;
2448 va_dcl
2449 #endif
2450 {
2451         va_list args;
2452
2453         VA_START(args, fmt);
2454         if (outf) {
2455                 int n = vfprintf(outf, fmt, args);
2456                 if (n < 0 && outf != stderr)
2457                         perror(outfname == NULL
2458                                ? "<writing to pipe>" : outfname);
2459                 else
2460                         curcol += n;
2461         }
2462         va_end(args);
2463         return;
2464 }
2465
2466 void
2467 printleader(tcp)
2468 struct tcb *tcp;
2469 {
2470         if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) {
2471                 tcp_last->flags |= TCB_REPRINT;
2472                 tprintf(" <unfinished ...>\n");
2473         }
2474         curcol = 0;
2475         if ((followfork == 1 || pflag_seen > 1) && outfname)
2476                 tprintf("%-5d ", tcp->pid);
2477         else if (nprocs > 1 && !outfname)
2478                 tprintf("[pid %5u] ", tcp->pid);
2479         if (tflag) {
2480                 char str[sizeof("HH:MM:SS")];
2481                 struct timeval tv, dtv;
2482                 static struct timeval otv;
2483
2484                 gettimeofday(&tv, NULL);
2485                 if (rflag) {
2486                         if (otv.tv_sec == 0)
2487                                 otv = tv;
2488                         tv_sub(&dtv, &tv, &otv);
2489                         tprintf("%6ld.%06ld ",
2490                                 (long) dtv.tv_sec, (long) dtv.tv_usec);
2491                         otv = tv;
2492                 }
2493                 else if (tflag > 2) {
2494                         tprintf("%ld.%06ld ",
2495                                 (long) tv.tv_sec, (long) tv.tv_usec);
2496                 }
2497                 else {
2498                         time_t local = tv.tv_sec;
2499                         strftime(str, sizeof(str), "%T", localtime(&local));
2500                         if (tflag > 1)
2501                                 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
2502                         else
2503                                 tprintf("%s ", str);
2504                 }
2505         }
2506         if (iflag)
2507                 printcall(tcp);
2508 }
2509
2510 void
2511 tabto(col)
2512 int col;
2513 {
2514         if (curcol < col)
2515                 tprintf("%*s", col - curcol, "");
2516 }
2517
2518 void
2519 printtrailer(tcp)
2520 struct tcb *tcp;
2521 {
2522         tprintf("\n");
2523         tcp_last = NULL;
2524 }
2525
2526 #ifdef HAVE_MP_PROCFS
2527
2528 int mp_ioctl (int fd, int cmd, void *arg, int size) {
2529
2530         struct iovec iov[2];
2531         int n = 1;
2532
2533         iov[0].iov_base = &cmd;
2534         iov[0].iov_len = sizeof cmd;
2535         if (arg) {
2536                 ++n;
2537                 iov[1].iov_base = arg;
2538                 iov[1].iov_len = size;
2539         }
2540
2541         return writev (fd, iov, n);
2542 }
2543
2544 #endif