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