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