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>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
33 #include <sys/types.h>
38 #include <sys/param.h>
40 #include <sys/resource.h>
48 #if defined(IA64) && defined(LINUX)
49 # include <asm/ptrace_offsets.h>
57 #include <sys/stropts.h>
65 int debug = 0, followfork = 0, followvfork = 0, interactive = 0;
66 int rflag = 0, tflag = 0, dtime = 0, cflag = 0;
67 int iflag = 0, xflag = 0, qflag = 0;
70 /* Sometimes we want to print only succeeding syscalls. */
71 int not_failing_only = 0;
73 char *username = NULL;
77 int acolumn = DEFAULT_ACOLUMN;
78 int max_strlen = DEFAULT_STRLEN;
79 char *outfname = NULL;
82 unsigned int nprocs, tcbtabsize;
84 extern char **environ;
86 static int trace P((void));
87 static void cleanup P((void));
88 static void interrupt P((int sig));
89 static sigset_t empty_set, blocked_set;
91 #ifdef HAVE_SIG_ATOMIC_T
92 static volatile sig_atomic_t interrupted;
93 #else /* !HAVE_SIG_ATOMIC_T */
95 static volatile int interrupted;
97 static int interrupted;
98 #endif /* !__STDC__ */
99 #endif /* !HAVE_SIG_ATOMIC_T */
103 static struct tcb *pfd2tcb P((int pfd));
104 static void reaper P((int sig));
105 static void rebuild_pollv P((void));
106 static struct pollfd *pollv;
108 #ifndef HAVE_POLLABLE_PROCFS
110 static void proc_poll_open P((void));
111 static void proc_poller P((int pfd));
119 static int poller_pid;
120 static int proc_poll_pipe[2] = { -1, -1 };
122 #endif /* !HAVE_POLLABLE_PROCFS */
124 #ifdef HAVE_MP_PROCFS
125 #define POLLWANT POLLWRNORM
127 #define POLLWANT POLLPRI
129 #endif /* USE_PROCFS */
137 usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\
138 [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\
139 [command [arg ...]]\n\
140 or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\
141 [command [arg ...]]\n\
142 -c -- count time, calls, and errors for each syscall and report summary\n\
143 -f -- follow forks, -ff -- with output into separate files\n\
144 -F -- attempt to follow vforks, -h -- print help message\n\
145 -i -- print instruction pointer at time of syscall\n\
146 -q -- suppress messages about attaching, detaching, etc.\n\
147 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
148 -T -- print time spent in each syscall, -V -- print version\n\
149 -v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\
150 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
151 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
152 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
153 options: trace, abbrev, verbose, raw, signal, read, or write\n\
154 -o file -- send trace output to FILE instead of stderr\n\
155 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
156 -p pid -- trace process with process id PID, may be repeated\n\
157 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
158 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
159 -u username -- run command as username handling setuid and/or setgid\n\
160 -E var=val -- put var=val in the environment for command\n\
161 -E var -- remove var from the environment for command\n\
162 " /* this is broken, so don't document it
163 -z -- print only succeeding syscalls\n\
165 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
189 static char buf[BUFSIZ];
191 /* Allocate the initial tcbtab. */
192 tcbtabsize = argc; /* Surely enough for all -p args. */
193 tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]);
194 tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]);
195 for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp)
196 tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]];
201 qualify("trace=all");
202 qualify("abbrev=all");
203 qualify("verbose=all");
204 qualify("signal=all");
205 set_sortby(DEFAULT_SORTBY);
206 set_personality(DEFAULT_PERSONALITY);
207 while ((c = getopt(argc, argv,
208 "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) {
246 qualify("abbrev=none");
249 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
253 not_failing_only = 1;
256 acolumn = atoi(optarg);
262 outfname = strdup(optarg);
265 set_overhead(atoi(optarg));
268 if ((pid = atoi(optarg)) <= 0) {
269 fprintf(stderr, "%s: Invalid process id: %s\n",
273 if (pid == getpid()) {
274 fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname);
277 if ((tcp = alloctcb(pid)) == NULL) {
278 fprintf(stderr, "%s: out of memory\n",
282 tcp->flags |= TCB_ATTACHED;
286 max_strlen = atoi(optarg);
292 username = strdup(optarg);
295 if (putenv(optarg) < 0) {
296 fprintf(stderr, "%s: out of memory\n",
307 /* See if they want to run as another user. */
308 if (username != NULL) {
311 if (getuid() != 0 || geteuid() != 0) {
313 "%s: you must be root to use the -u option\n",
317 if ((pent = getpwnam(username)) == NULL) {
318 fprintf(stderr, "%s: cannot find user `%s'\n",
322 run_uid = pent->pw_uid;
323 run_gid = pent->pw_gid;
331 setreuid(geteuid(), getuid());
334 /* See if they want to pipe the output. */
335 if (outfname && (outfname[0] == '|' || outfname[0] == '!')) {
336 if ((outf = popen(outfname + 1, "w")) == NULL) {
337 fprintf(stderr, "%s: can't popen '%s': %s\n",
338 progname, outfname + 1, strerror(errno));
345 /* Check if they want to redirect the output. */
349 if ((outf = fopen(outfname, "w")) == NULL) {
350 fprintf(stderr, "%s: can't fopen '%s': %s\n",
351 progname, outfname, strerror(errno));
355 if ((f=fcntl(fileno(outf), F_GETFD)) < 0 ) {
356 perror("failed to get flags for outputfile");
360 if (fcntl(fileno(outf), F_SETFD, f|FD_CLOEXEC) < 0 ) {
361 perror("failed to set flags for outputfile");
367 setreuid(geteuid(), getuid());
371 setvbuf(outf, buf, _IOLBF, BUFSIZ);
373 else if (optind < argc) {
378 for (c = 0; c < tcbtabsize; c++) {
380 /* Reinitialize the output since it may have changed. */
382 if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
385 if (proc_open(tcp, 1) < 0) {
386 fprintf(stderr, "trouble opening proc file\n");
390 #else /* !USE_PROCFS */
391 if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
392 perror("attach: ptrace(PTRACE_ATTACH, ...)");
396 #endif /* !USE_PROCFS */
399 "Process %u attached - interrupt to quit\n",
406 char pathname[MAXPATHLEN];
408 filename = argv[optind];
409 if (strchr(filename, '/'))
410 strcpy(pathname, filename);
411 #ifdef USE_DEBUGGING_EXEC
413 * Debuggers customarily check the current directory
414 * first regardless of the path but doing that gives
415 * security geeks a panic attack.
417 else if (stat(filename, &statbuf) == 0)
418 strcpy(pathname, filename);
419 #endif /* USE_DEBUGGING_EXEC */
424 for (path = getenv("PATH"); path && *path; path += m) {
425 if (strchr(path, ':')) {
426 n = strchr(path, ':') - path;
430 m = n = strlen(path);
432 getcwd(pathname, MAXPATHLEN);
433 len = strlen(pathname);
436 strncpy(pathname, path, n);
439 if (len && pathname[len - 1] != '/')
440 pathname[len++] = '/';
441 strcpy(pathname + len, filename);
442 if (stat(pathname, &statbuf) == 0 &&
443 /* Accept only regular files
444 with some execute bits set.
445 XXX not perfect, might still fail */
446 S_ISREG(statbuf.st_mode) &&
447 (statbuf.st_mode & 0111))
451 if (stat(pathname, &statbuf) < 0) {
452 fprintf(stderr, "%s: %s: command not found\n",
456 switch (pid = fork()) {
458 perror("strace: fork");
464 if (outf != stderr) close (fileno (outf));
466 /* Kludge for SGI, see proc_open for details. */
467 sa.sa_handler = foobar;
469 sigemptyset(&sa.sa_mask);
470 sigaction(SIGINT, &sa, NULL);
475 kill(getpid(), SIGSTOP); /* stop HERE */
477 #else /* !USE_PROCFS */
479 close(fileno (outf));
481 if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) {
482 perror("strace: ptrace(PTRACE_TRACEME, ...)");
486 kill(getpid(), SIGSTOP);
488 if (username != NULL || geteuid() == 0) {
489 uid_t run_euid = run_uid;
490 gid_t run_egid = run_gid;
492 if (statbuf.st_mode & S_ISUID)
493 run_euid = statbuf.st_uid;
494 if (statbuf.st_mode & S_ISGID)
495 run_egid = statbuf.st_gid;
498 * It is important to set groups before we
499 * lose privileges on setuid.
501 if (username != NULL) {
502 if (initgroups(username, run_gid) < 0) {
503 perror("initgroups");
506 if (setregid(run_gid, run_egid) < 0) {
510 if (setreuid(run_uid, run_euid) < 0) {
517 setreuid(run_uid, run_uid);
518 #endif /* !USE_PROCFS */
520 execv(pathname, &argv[optind]);
521 perror("strace: exec");
526 if ((tcp = alloctcb(pid)) == NULL) {
527 fprintf(stderr, "tcb table full\n");
532 if (proc_open(tcp, 0) < 0) {
533 fprintf(stderr, "trouble opening proc file\n");
537 #endif /* USE_PROCFS */
539 fake_execve(tcp, pathname, &argv[optind], environ);
540 #endif /* !USE_PROCFS */
544 else if (pflag_seen == 0)
547 sigemptyset(&empty_set);
548 sigemptyset(&blocked_set);
549 sa.sa_handler = SIG_IGN;
550 sigemptyset(&sa.sa_mask);
552 sigaction(SIGTTOU, &sa, NULL);
553 sigaction(SIGTTIN, &sa, NULL);
555 sigaddset(&blocked_set, SIGHUP);
556 sigaddset(&blocked_set, SIGINT);
557 sigaddset(&blocked_set, SIGQUIT);
558 sigaddset(&blocked_set, SIGPIPE);
559 sigaddset(&blocked_set, SIGTERM);
560 sa.sa_handler = interrupt;
562 /* POSIX signals on sunos4.1 are a little broken. */
563 sa.sa_flags = SA_INTERRUPT;
566 sigaction(SIGHUP, &sa, NULL);
567 sigaction(SIGINT, &sa, NULL);
568 sigaction(SIGQUIT, &sa, NULL);
569 sigaction(SIGPIPE, &sa, NULL);
570 sigaction(SIGTERM, &sa, NULL);
572 sa.sa_handler = reaper;
573 sigaction(SIGCHLD, &sa, NULL);
575 /* Make sure SIGCHLD has the default action so that waitpid
576 definitely works without losing track of children. The user
577 should not have given us a bogus state to inherit, but he might
578 have. Arguably we should detect SIG_IGN here and pass it on
579 to children, but probably noone really needs that. */
580 sa.sa_handler = SIG_DFL;
581 sigaction(SIGCHLD, &sa, NULL);
582 #endif /* USE_PROCFS */
594 char name[MAXPATHLEN];
597 if (outfname && followfork > 1) {
598 sprintf(name, "%s.%u", outfname, tcp->pid);
600 setreuid(geteuid(), getuid());
602 fp = fopen(name, "w");
604 setreuid(geteuid(), getuid());
622 for (i = 0; i < tcbtabsize; i++) {
624 if ((tcp->flags & TCB_INUSE) == 0) {
629 #ifdef TCB_CLONE_THREAD
630 tcp->nclone_threads = tcp->nclone_detached = 0;
631 tcp->nclone_waiting = 0;
633 tcp->flags = TCB_INUSE | TCB_STARTUP;
634 tcp->outf = outf; /* Initialise to current out file */
635 tcp->stime.tv_sec = 0;
636 tcp->stime.tv_usec = 0;
647 proc_open(tcp, attaching)
659 #ifndef HAVE_POLLABLE_PROCFS
663 #ifdef HAVE_MP_PROCFS
664 /* Open the process pseudo-files in /proc. */
665 sprintf(proc, "/proc/%d/ctl", tcp->pid);
666 if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
667 perror("strace: open(\"/proc/...\", ...)");
670 if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
674 if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
678 sprintf(proc, "/proc/%d/status", tcp->pid);
679 if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
680 perror("strace: open(\"/proc/...\", ...)");
683 if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) {
687 if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) {
691 sprintf(proc, "/proc/%d/as", tcp->pid);
692 if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
693 perror("strace: open(\"/proc/...\", ...)");
696 if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) {
700 if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) {
705 /* Open the process pseudo-file in /proc. */
707 sprintf(proc, "/proc/%d", tcp->pid);
708 if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
710 sprintf(proc, "/proc/%d/mem", tcp->pid);
711 if ((tcp->pfd = open(proc, O_RDWR)) < 0) {
713 perror("strace: open(\"/proc/...\", ...)");
716 if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
720 if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
726 sprintf(proc, "/proc/%d/regs", tcp->pid);
727 if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) {
728 perror("strace: open(\"/proc/.../regs\", ...)");
732 sprintf(proc, "/proc/%d/status", tcp->pid);
733 if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) {
734 perror("strace: open(\"/proc/.../status\", ...)");
738 tcp->pfd_status = -1;
743 * Wait for the child to pause. Because of a race
744 * condition we have to poll for the event.
747 if (IOCTL_STATUS (tcp) < 0) {
748 perror("strace: PIOCSTATUS");
751 if (tcp->status.PR_FLAGS & PR_ASLEEP)
756 /* Stop the process so that we own the stop. */
757 if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) {
758 perror("strace: PIOCSTOP");
763 /* Set Run-on-Last-Close. */
765 if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
766 perror("PIOCSET PR_RLC");
769 /* Set or Reset Inherit-on-Fork. */
771 if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
772 perror("PIOC{SET,RESET} PR_FORK");
777 if (ioctl(tcp->pfd, PIOCSRLC) < 0) {
781 if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) {
782 perror("PIOC{S,R}FORK");
786 /* just unset the PF_LINGER flag for the Run-on-Last-Close. */
787 if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) {
792 if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) {
797 #endif /* !PIOCSET */
799 /* Enable all syscall entries we care about. */
800 premptyset(&syscalls);
801 for (i = 1; i < MAX_QUALS; ++i) {
802 if (i > (sizeof syscalls) * CHAR_BIT) break;
803 if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i);
805 praddset (&syscalls, SYS_execve);
807 praddset (&syscalls, SYS_fork);
809 praddset (&syscalls, SYS_forkall);
812 praddset (&syscalls, SYS_fork1);
815 praddset (&syscalls, SYS_rfork1);
818 praddset (&syscalls, SYS_rforkall);
821 if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) {
822 perror("PIOCSENTRY");
825 /* Enable the syscall exits. */
826 if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) {
830 /* Enable signals we care about. */
831 premptyset(&signals);
832 for (i = 1; i < MAX_QUALS; ++i) {
833 if (i > (sizeof signals) * CHAR_BIT) break;
834 if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i);
836 if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
837 perror("PIOCSTRACE");
840 /* Enable faults we care about */
842 for (i = 1; i < MAX_QUALS; ++i) {
843 if (i > (sizeof faults) * CHAR_BIT) break;
844 if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i);
846 if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
847 perror("PIOCSFAULT");
851 /* set events flags. */
852 arg = S_SIG | S_SCE | S_SCX ;
853 if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) {
861 * The SGI PRSABORT doesn't work for pause() so
862 * we send it a caught signal to wake it up.
864 kill(tcp->pid, SIGINT);
867 /* The child is in a pause(), abort it. */
869 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
876 /* wake up the child if it received the SIGSTOP */
877 kill(tcp->pid, SIGCONT);
880 /* Wait for the child to do something. */
881 if (IOCTL_WSTOP (tcp) < 0) {
885 if (tcp->status.PR_WHY == PR_SYSENTRY) {
886 tcp->flags &= ~TCB_INSYSCALL;
888 if (tcp->scno == SYS_execve)
891 /* Set it running: maybe execve will be next. */
894 if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
896 if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) {
902 /* handle the case where we "opened" the child before
903 it did the kill -STOP */
904 if (tcp->status.PR_WHY == PR_SIGNALLED &&
905 tcp->status.PR_WHAT == SIGSTOP)
906 kill(tcp->pid, SIGCONT);
914 /* We are attaching to an already running process.
915 * Try to figure out the state of the process in syscalls,
916 * to handle the first event well.
917 * This is done by having a look at the "wchan" property of the
918 * process, which tells where it is stopped (if it is). */
920 char wchan[20]; /* should be enough */
922 sprintf(proc, "/proc/%d/status", tcp->pid);
923 status = fopen(proc, "r");
925 (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d"
926 "%*d,%*d %*d,%*d %19s", wchan) == 1) &&
927 strcmp(wchan, "nochan") && strcmp(wchan, "spread") &&
928 strcmp(wchan, "stopevent")) {
929 /* The process is asleep in the middle of a syscall.
930 Fake the syscall entry event */
931 tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP);
932 tcp->status.PR_WHY = PR_SYSENTRY;
937 } /* otherwise it's a fork being followed */
940 #ifndef HAVE_POLLABLE_PROCFS
941 if (proc_poll_pipe[0] != -1)
942 proc_poller(tcp->pfd);
943 else if (nprocs > 1) {
945 proc_poller(last_pfd);
946 proc_poller(tcp->pfd);
949 #endif /* !HAVE_POLLABLE_PROCFS */
953 #endif /* USE_PROCFS */
962 for (i = 0; i < tcbtabsize; i++) {
964 if (pid && tcp->pid != pid)
966 if (tcp->flags & TCB_INUSE)
980 for (i = 0; i < tcbtabsize; i++) {
981 struct tcb *tcp = tcbtab[i];
984 if (tcp->flags & TCB_INUSE)
990 #endif /* USE_PROCFS */
998 #ifdef TCB_CLONE_THREAD
999 if (tcp->nclone_threads > 0) {
1000 /* There are other threads left in this process, but this
1001 is the one whose PID represents the whole process.
1002 We need to keep this record around as a zombie until
1003 all the threads die. */
1004 tcp->flags |= TCB_EXITING;
1011 if (tcp->parent != NULL) {
1012 tcp->parent->nchildren--;
1013 #ifdef TCB_CLONE_THREAD
1014 if (tcp->flags & TCB_CLONE_DETACHED)
1015 tcp->parent->nclone_detached--;
1016 if (tcp->flags & TCB_CLONE_THREAD)
1017 tcp->parent->nclone_threads--;
1019 #ifdef TCB_CLONE_DETACHED
1020 if (!(tcp->flags & TCB_CLONE_DETACHED))
1022 tcp->parent->nzombies++;
1027 if (tcp->pfd != -1) {
1031 if (tcp->pfd_reg != -1) {
1032 close(tcp->pfd_reg);
1035 if (tcp->pfd_status != -1) {
1036 close(tcp->pfd_status);
1037 tcp->pfd_status = -1;
1039 #endif /* !FREEBSD */
1041 rebuild_pollv(); /* Note, flags needs to be cleared by now. */
1045 if (outfname && followfork > 1 && tcp->outf)
1060 if (!(tcp->flags & TCB_SUSPENDED)) {
1061 fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid);
1064 tcp->flags &= ~TCB_SUSPENDED;
1065 #ifdef TCB_CLONE_THREAD
1066 if (tcp->flags & TCB_CLONE_THREAD)
1067 tcp->parent->nclone_waiting--;
1070 if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) {
1071 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
1076 fprintf(stderr, "Process %u resumed\n", tcp->pid);
1080 #endif /* !USE_PROCFS */
1082 /* detach traced process; continue with sig */
1091 int status, resumed;
1094 if (tcp->flags & TCB_BPTSET)
1099 * Linux wrongly insists the child be stopped
1100 * before detaching. Arghh. We go through hoops
1101 * to make a clean break of things.
1104 #undef PTRACE_DETACH
1105 #define PTRACE_DETACH PTRACE_SUNDETACH
1107 if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) {
1108 /* On a clear day, you can see forever. */
1110 else if (errno != ESRCH) {
1111 /* Shouldn't happen. */
1112 perror("detach: ptrace(PTRACE_DETACH, ...)");
1114 else if (kill(tcp->pid, 0) < 0) {
1116 perror("detach: checking sanity");
1118 else if (kill(tcp->pid, SIGSTOP) < 0) {
1120 perror("detach: stopping child");
1125 if (wait4(tcp->pid, &status, __WALL, NULL) < 0) {
1126 if (errno == ECHILD) /* Already gone. */
1128 if (errno != EINVAL) {
1129 perror("detach: waiting");
1133 /* No __WALL here. */
1134 if (waitpid(tcp->pid, &status, 0) < 0) {
1135 if (errno != ECHILD) {
1136 perror("detach: waiting");
1140 /* If no processes, try clones. */
1141 if (wait4(tcp->pid, &status, __WCLONE,
1143 if (errno != ECHILD)
1144 perror("detach: waiting");
1147 #endif /* __WCLONE */
1152 if (!WIFSTOPPED(status)) {
1153 /* Au revoir, mon ami. */
1156 if (WSTOPSIG(status) == SIGSTOP) {
1157 if ((error = ptrace(PTRACE_DETACH,
1158 tcp->pid, (char *) 1, sig)) < 0) {
1160 perror("detach: ptrace(PTRACE_DETACH, ...)");
1161 /* I died trying. */
1165 if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1,
1166 WSTOPSIG(status) == SIGTRAP ?
1167 0 : WSTOPSIG(status))) < 0) {
1169 perror("detach: ptrace(PTRACE_CONT, ...)");
1177 /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */
1178 if (sig && kill(tcp->pid, sig) < 0)
1179 perror("detach: kill");
1181 if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0)
1182 perror("detach: ptrace(PTRACE_DETACH, ...)");
1188 /* XXX This won't always be quite right (but it never was).
1189 A waiter with argument 0 or < -1 is waiting for any pid in
1190 a particular pgrp, which this child might or might not be
1191 in. The waiter will only wake up if it's argument is -1
1192 or if it's waiting for tcp->pid's pgrp. It makes a
1193 difference to wake up a waiter when there might be more
1194 traced children, because it could get a false ECHILD
1195 error. OTOH, if this was the last child in the pgrp, then
1196 it ought to wake up and get ECHILD. We would have to
1197 search the system for all pid's in the pgrp to be sure.
1199 && (t->waitpid == -1 ||
1200 (t->waitpid == 0 && getpgid (tcp->pid) == getpgid (t->pid))
1201 || (t->waitpid < 0 && t->waitpid == -getpid (t->pid)))
1205 (tcp->parent->flags & TCB_SUSPENDED) &&
1206 (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) {
1207 error = resume(tcp->parent);
1210 #ifdef TCB_CLONE_THREAD
1211 if (tcp->parent && tcp->parent->nclone_waiting > 0) {
1212 /* Some other threads of our parent are waiting too. */
1215 /* Resume all the threads that were waiting for this PID. */
1216 for (i = 0; i < tcbtabsize; i++) {
1217 struct tcb *t = tcbtab[i];
1218 if (t->parent == tcp->parent && t != tcp
1219 && ((t->flags & (TCB_CLONE_THREAD|TCB_SUSPENDED))
1220 == (TCB_CLONE_THREAD|TCB_SUSPENDED))
1221 && t->waitpid == tcp->pid) {
1222 error |= resume (t);
1227 /* Noone was waiting for this PID in particular,
1228 so now we might need to resume some wildcarders. */
1229 for (i = 0; i < tcbtabsize; i++) {
1230 struct tcb *t = tcbtab[i];
1231 if (t->parent == tcp->parent && t != tcp
1233 & (TCB_CLONE_THREAD|TCB_SUSPENDED))
1234 == (TCB_CLONE_THREAD|TCB_SUSPENDED))
1237 error |= resume (t);
1244 #endif /* !USE_PROCFS */
1247 fprintf(stderr, "Process %u detached\n", tcp->pid);
1262 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
1273 #endif /* USE_PROCFS */
1281 for (i = 0; i < tcbtabsize; i++) {
1283 if (!(tcp->flags & TCB_INUSE))
1287 "cleanup: looking at pid %u\n", tcp->pid);
1289 (!outfname || followfork < 2 || tcp_last == tcp)) {
1290 tprintf(" <unfinished ...>\n");
1293 if (tcp->flags & TCB_ATTACHED)
1296 kill(tcp->pid, SIGCONT);
1297 kill(tcp->pid, SIGTERM);
1311 #ifndef HAVE_STRERROR
1313 #if !HAVE_DECL_SYS_ERRLIST
1314 extern int sys_nerr;
1315 extern char *sys_errlist[];
1316 #endif /* HAVE_DECL_SYS_ERRLIST */
1322 static char buf[64];
1324 if (errno < 1 || errno >= sys_nerr) {
1325 sprintf(buf, "Unknown error %d", errno);
1328 return sys_errlist[errno];
1331 #endif /* HAVE_STERRROR */
1333 #ifndef HAVE_STRSIGNAL
1335 #if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
1336 extern char *sys_siglist[];
1338 #if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1339 extern char *_sys_siglist[];
1346 static char buf[64];
1348 if (sig < 1 || sig >= NSIG) {
1349 sprintf(buf, "Unknown signal %d", sig);
1352 #ifdef HAVE__SYS_SIGLIST
1353 return _sys_siglist[sig];
1355 return sys_siglist[sig];
1359 #endif /* HAVE_STRSIGNAL */
1370 pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]);
1371 if (pollv == NULL) {
1372 fprintf(stderr, "strace: out of memory for poll vector\n");
1376 for (i = j = 0; i < tcbtabsize; i++) {
1377 struct tcb *tcp = tcbtab[i];
1378 if (!(tcp->flags & TCB_INUSE))
1380 pollv[j].fd = tcp->pfd;
1381 pollv[j].events = POLLWANT;
1385 fprintf(stderr, "strace: proc miscount\n");
1390 #ifndef HAVE_POLLABLE_PROCFS
1398 if (pipe(proc_poll_pipe) < 0) {
1402 for (i = 0; i < 2; i++) {
1403 if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) {
1407 if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) {
1415 proc_poll(pollv, nfds, timeout)
1416 struct pollfd *pollv;
1422 struct proc_pollfd pollinfo;
1424 if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0)
1426 if (n != sizeof(struct proc_pollfd)) {
1427 fprintf(stderr, "panic: short read: %d\n", n);
1430 for (i = 0; i < nprocs; i++) {
1431 if (pollv[i].fd == pollinfo.fd)
1432 pollv[i].revents = pollinfo.revents;
1434 pollv[i].revents = 0;
1436 poller_pid = pollinfo.pid;
1450 struct proc_pollfd pollinfo;
1451 struct sigaction sa;
1452 sigset_t blocked_set, empty_set;
1457 struct procfs_status pfs;
1458 #endif /* FREEBSD */
1470 sa.sa_handler = interactive ? SIG_DFL : SIG_IGN;
1472 sigemptyset(&sa.sa_mask);
1473 sigaction(SIGHUP, &sa, NULL);
1474 sigaction(SIGINT, &sa, NULL);
1475 sigaction(SIGQUIT, &sa, NULL);
1476 sigaction(SIGPIPE, &sa, NULL);
1477 sigaction(SIGTERM, &sa, NULL);
1478 sa.sa_handler = wakeup_handler;
1479 sigaction(SIGUSR1, &sa, NULL);
1480 sigemptyset(&blocked_set);
1481 sigaddset(&blocked_set, SIGUSR1);
1482 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1483 sigemptyset(&empty_set);
1485 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
1486 perror("getrlimit(RLIMIT_NOFILE, ...)");
1490 for (i = 0; i < n; i++) {
1491 if (i != pfd && i != proc_poll_pipe[1])
1496 pollinfo.pid = getpid();
1499 if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
1501 if (ioctl(pfd, PIOCWSTOP, &pfs) < 0)
1502 #endif /* FREEBSD */
1508 pollinfo.revents = POLLERR;
1511 pollinfo.revents = POLLHUP;
1514 perror("proc_poller: PIOCWSTOP");
1516 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1519 pollinfo.revents = POLLWANT;
1520 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
1521 sigsuspend(&empty_set);
1525 #endif /* !HAVE_POLLABLE_PROCFS */
1535 if (followfork < 2 &&
1536 last < nprocs && (pollv[last].revents & POLLWANT)) {
1538 * The previous process is ready to run again. We'll
1539 * let it do so if it is currently in a syscall. This
1540 * heuristic improves the readability of the trace.
1542 tcp = pfd2tcb(pollv[last].fd);
1543 if (tcp && (tcp->flags & TCB_INSYSCALL))
1544 return pollv[last].fd;
1547 for (i = 0; i < nprocs; i++) {
1548 /* Let competing children run round robin. */
1549 j = (i + last + 1) % nprocs;
1550 if (pollv[j].revents & (POLLHUP | POLLERR)) {
1551 tcp = pfd2tcb(pollv[j].fd);
1553 fprintf(stderr, "strace: lost proc\n");
1559 if (pollv[j].revents & POLLWANT) {
1564 fprintf(stderr, "strace: nothing ready\n");
1572 struct tcb *in_syscall = NULL;
1577 int ioctl_result = 0, ioctl_errno = 0;
1582 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1589 #ifndef HAVE_POLLABLE_PROCFS
1590 if (proc_poll_pipe[0] == -1) {
1599 #ifndef HAVE_POLLABLE_PROCFS
1601 /* fall through ... */
1602 #endif /* !HAVE_POLLABLE_PROCFS */
1604 #ifdef HAVE_POLLABLE_PROCFS
1606 /* On some systems (e.g. UnixWare) we get too much ugly
1607 "unfinished..." stuff when multiple proceses are in
1608 syscalls. Here's a nasty hack */
1615 pv.events = POLLWANT;
1616 if ((what = poll (&pv, 1, 1)) < 0) {
1621 else if (what == 1 && pv.revents & POLLWANT) {
1627 if (poll(pollv, nprocs, INFTIM) < 0) {
1632 #else /* !HAVE_POLLABLE_PROCFS */
1633 if (proc_poll(pollv, nprocs, INFTIM) < 0) {
1638 #endif /* !HAVE_POLLABLE_PROCFS */
1645 /* Look up `pfd' in our table. */
1646 if ((tcp = pfd2tcb(pfd)) == NULL) {
1647 fprintf(stderr, "unknown pfd: %u\n", pfd);
1653 /* Get the status of the process. */
1656 ioctl_result = IOCTL_WSTOP (tcp);
1658 /* Thanks to some scheduling mystery, the first poller
1659 sometimes waits for the already processed end of fork
1660 event. Doing a non blocking poll here solves the problem. */
1661 if (proc_poll_pipe[0] != -1)
1662 ioctl_result = IOCTL_STATUS (tcp);
1664 ioctl_result = IOCTL_WSTOP (tcp);
1665 #endif /* FREEBSD */
1666 ioctl_errno = errno;
1667 #ifndef HAVE_POLLABLE_PROCFS
1668 if (proc_poll_pipe[0] != -1) {
1669 if (ioctl_result < 0)
1670 kill(poller_pid, SIGKILL);
1672 kill(poller_pid, SIGUSR1);
1674 #endif /* !HAVE_POLLABLE_PROCFS */
1680 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1682 if (ioctl_result < 0) {
1683 /* Find out what happened if it failed. */
1684 switch (ioctl_errno) {
1695 perror("PIOCWSTOP");
1701 if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) {
1702 /* discard first event for a syscall we never entered */
1703 IOCTL (tcp->pfd, PIOCRUN, 0);
1708 /* clear the just started flag */
1709 tcp->flags &= ~TCB_STARTUP;
1711 /* set current output file */
1715 struct timeval stime;
1720 if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) {
1723 "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld",
1724 &stime.tv_sec, &stime.tv_usec);
1726 stime.tv_sec = stime.tv_usec = 0;
1727 #else /* !FREEBSD */
1728 stime.tv_sec = tcp->status.pr_stime.tv_sec;
1729 stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000;
1730 #endif /* !FREEBSD */
1731 tv_sub(&tcp->dtime, &stime, &tcp->stime);
1734 what = tcp->status.PR_WHAT;
1735 switch (tcp->status.PR_WHY) {
1738 if (tcp->status.PR_FLAGS & PR_ASLEEP) {
1739 tcp->status.PR_WHY = PR_SYSENTRY;
1740 if (trace_syscall(tcp) < 0) {
1741 fprintf(stderr, "syscall trouble\n");
1746 #endif /* !FREEBSD */
1752 if (trace_syscall(tcp) < 0) {
1753 fprintf(stderr, "syscall trouble\n");
1758 if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) {
1760 tprintf("--- %s (%s) ---",
1761 signame(what), strsignal(what));
1764 if (tcp->status.PR_INFO.si_signo == what) {
1766 tprintf(" siginfo=");
1767 printsiginfo(&tcp->status.PR_INFO, 1);
1774 if (!cflag && (qual_flags[what] & QUAL_FAULT)) {
1776 tprintf("=== FAULT %d ===", what);
1781 case 0: /* handle case we polled for nothing */
1785 fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
1791 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
1793 if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) {
1802 #else /* !USE_PROCFS */
1804 #ifdef TCB_GROUP_EXITING
1805 /* Handle an exit detach or death signal that is taking all the
1806 related clone threads with it. This is called in three circumstances:
1807 SIG == -1 TCP has already died (TCB_ATTACHED is clear, strace is parent).
1808 SIG == 0 Continuing TCP will perform an exit_group syscall.
1809 SIG == other Continuing TCP with SIG will kill the process.
1812 handle_group_exit(struct tcb *tcp, int sig)
1814 /* We need to locate our records of all the clone threads
1815 related to TCP, either its children or siblings. */
1816 struct tcb *leader = ((tcp->flags & TCB_CLONE_THREAD)
1818 : tcp->nclone_detached > 0
1822 if (leader != NULL && leader != tcp)
1824 "PANIC: handle_group_exit: %d leader %d\n",
1825 tcp->pid, leader ? leader->pid : -1);
1826 droptcb(tcp); /* Already died. */
1829 if (tcp->flags & TCB_ATTACHED) {
1830 if (leader != NULL && leader != tcp) {
1831 /* We need to detach the leader so that the
1832 process death will be reported to its real
1833 parent. But we kill it first to prevent
1834 it doing anything before we kill the whole
1835 process in a moment. We can use
1836 PTRACE_KILL on a thread that's not already
1837 stopped. Then the value we pass in
1838 PTRACE_DETACH just sets the death
1839 signal reported to the real parent. */
1840 ptrace(PTRACE_KILL, leader->pid, 0, 0);
1843 " [%d exit %d kills %d]\n",
1844 tcp->pid, sig, leader->pid);
1845 detach(leader, sig);
1849 else if (ptrace(PTRACE_CONT, tcp->pid, (char *) 1, sig) < 0) {
1850 perror("strace: ptrace(PTRACE_CONT, ...)");
1855 if (leader != NULL && leader != tcp)
1857 /* The leader will report to us as parent now,
1858 and then we'll get to the SIG==-1 case. */
1863 /* Note that TCP and LEADER are no longer valid,
1864 but we can still compare against them. */
1865 if (leader != NULL) {
1867 for (i = 0; i < tcbtabsize; i++) {
1868 struct tcb *t = tcbtab[i];
1869 if (t != tcp && (t->flags & TCB_CLONE_DETACHED)
1870 && t->parent == leader)
1889 static int wait4_options = __WALL;
1893 while (nprocs != 0) {
1895 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1898 pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL);
1899 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1900 /* this kernel does not support __WALL */
1901 wait4_options &= ~__WALL;
1903 pid = wait4(-1, &status, wait4_options,
1904 cflag ? &ru : NULL);
1906 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1907 /* most likely a "cloned" process */
1908 pid = wait4(-1, &status, __WCLONE,
1909 cflag ? &ru : NULL);
1911 fprintf(stderr, "strace: clone wait4 "
1912 "failed: %s\n", strerror(errno));
1916 pid = wait4(-1, &status, 0, cflag ? &ru : NULL);
1920 pid = wait(&status);
1924 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1930 switch (wait_errno) {
1935 * We would like to verify this case
1936 * but sometimes a race in Solbourne's
1937 * version of SunOS sometimes reports
1938 * ECHILD before sending us SIGCHILD.
1943 fprintf(stderr, "strace: proc miscount\n");
1949 perror("strace: wait");
1954 fprintf(stderr, " [wait(%#x) = %u]\n", status, pid);
1956 /* Look up `pid' in our table. */
1957 if ((tcp = pid2tcb(pid)) == NULL) {
1959 if (followfork || followvfork) {
1960 /* This is needed to go with the CLONE_PTRACE
1961 changes in process.c/util.c: we might see
1962 the child's initial trap before we see the
1963 parent return from the clone syscall.
1964 Leave the child suspended until the parent
1965 returns from its system call. Only then
1966 will we have the association of parent and
1967 child so that we know how to do clearbpt
1969 if ((tcp = alloctcb(pid)) == NULL) {
1970 fprintf(stderr, " [tcb table full]\n");
1971 kill(pid, SIGKILL); /* XXX */
1974 tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED;
1978 Process %d attached (waiting for parent)\n",
1982 /* This can happen if a clone call used
1983 CLONE_PTRACE itself. */
1986 fprintf(stderr, "unknown pid: %u\n", pid);
1987 if (WIFSTOPPED(status))
1988 ptrace(PTRACE_CONT, pid, (char *) 1, 0);
1992 /* set current output file */
1996 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1997 tcp->stime = ru.ru_stime;
2001 if (tcp->flags & TCB_SUSPENDED) {
2003 * Apparently, doing any ptrace() call on a stopped
2004 * process, provokes the kernel to report the process
2005 * status again on a subsequent wait(), even if the
2006 * process has not been actually restarted.
2007 * Since we have inspected the arguments of suspended
2008 * processes we end up here testing for this case.
2012 if (WIFSIGNALED(status)) {
2014 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2016 tprintf("+++ killed by %s +++",
2017 signame(WTERMSIG(status)));
2020 #ifdef TCB_GROUP_EXITING
2021 handle_group_exit(tcp, -1);
2027 if (WIFEXITED(status)) {
2029 fprintf(stderr, "pid %u exited\n", pid);
2030 if (tcp->flags & TCB_ATTACHED)
2032 "PANIC: attached pid %u exited\n",
2034 if (tcp == tcp_last) {
2035 if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT))
2037 tprintf(" <unfinished ... exit status %d>\n",
2038 WEXITSTATUS(status));
2041 #ifdef TCB_GROUP_EXITING
2042 handle_group_exit(tcp, -1);
2048 if (!WIFSTOPPED(status)) {
2049 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2054 fprintf(stderr, "pid %u stopped, [%s]\n",
2055 pid, signame(WSTOPSIG(status)));
2057 if (tcp->flags & TCB_STARTUP) {
2059 * This flag is there to keep us in sync.
2060 * Next time this process stops it should
2061 * really be entering a system call.
2063 tcp->flags &= ~TCB_STARTUP;
2064 if (tcp->flags & TCB_ATTACHED) {
2066 * Interestingly, the process may stop
2067 * with STOPSIG equal to some other signal
2068 * than SIGSTOP if we happend to attach
2069 * just before the process takes a signal.
2071 if (!WIFSTOPPED(status)) {
2073 "pid %u not stopped\n", pid);
2074 detach(tcp, WSTOPSIG(status));
2080 /* A child of us stopped at exec */
2081 if (WSTOPSIG(status) == SIGTRAP && followvfork)
2085 if (tcp->flags & TCB_BPTSET) {
2086 if (clearbpt(tcp) < 0) /* Pretty fatal */ {
2095 if (WSTOPSIG(status) != SIGTRAP) {
2096 if (WSTOPSIG(status) == SIGSTOP &&
2097 (tcp->flags & TCB_SIGTRAPPED)) {
2099 * Trapped attempt to block SIGTRAP
2100 * Hope we are back in control now.
2102 tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED);
2103 if (ptrace(PTRACE_SYSCALL,
2104 pid, (char *) 1, 0) < 0) {
2105 perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2112 && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) {
2113 unsigned long addr = 0, pc = 0;
2114 #ifdef PT_GETSIGINFO
2119 upeek(pid, PT_CR_IPSR, &psr);
2120 upeek(pid, PT_CR_IIP, &pc);
2122 pc += (psr >> PSR_RI) & 0x3;
2123 ptrace(PT_GETSIGINFO, pid, 0, (long) &si);
2124 addr = (unsigned long) si.si_addr;
2127 tprintf("--- %s (%s) @ %lx (%lx) ---",
2128 signame(WSTOPSIG(status)),
2129 strsignal(WSTOPSIG(status)), pc, addr);
2132 if ((tcp->flags & TCB_ATTACHED) &&
2133 !sigishandled(tcp, WSTOPSIG(status))) {
2134 #ifdef TCB_GROUP_EXITING
2135 handle_group_exit(tcp, WSTOPSIG(status));
2137 detach(tcp, WSTOPSIG(status));
2141 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1,
2142 WSTOPSIG(status)) < 0) {
2143 perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2147 tcp->flags &= ~TCB_SUSPENDED;
2150 if (trace_syscall(tcp) < 0) {
2151 if (tcp->flags & TCB_ATTACHED)
2155 tcp->pid, (char *) 1, SIGTERM);
2160 if (tcp->flags & TCB_EXITING) {
2161 #ifdef TCB_GROUP_EXITING
2162 if (tcp->flags & TCB_GROUP_EXITING) {
2163 if (handle_group_exit(tcp, 0) < 0)
2168 if (tcp->flags & TCB_ATTACHED)
2170 else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) {
2171 perror("strace: ptrace(PTRACE_CONT, ...)");
2177 if (tcp->flags & TCB_SUSPENDED) {
2179 fprintf(stderr, "Process %u suspended\n", pid);
2183 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
2184 perror("trace: ptrace(PTRACE_SYSCALL, ...)");
2192 #endif /* !USE_PROCFS */
2198 #define VA_START(a, b) va_start(a, b)
2200 #include <varargs.h>
2201 #define VA_START(a, b) va_start(a)
2206 tprintf(const char *fmt, ...)
2208 tprintf(fmt, va_alist)
2215 VA_START(args, fmt);
2217 curcol += vfprintf(outf, fmt, args);
2226 if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) {
2227 tcp_last->flags |= TCB_REPRINT;
2228 tprintf(" <unfinished ...>\n");
2231 if ((followfork == 1 || pflag_seen > 1) && outfname)
2232 tprintf("%-5d ", tcp->pid);
2233 else if (nprocs > 1 && !outfname)
2234 tprintf("[pid %5u] ", tcp->pid);
2236 char str[sizeof("HH:MM:SS")];
2237 struct timeval tv, dtv;
2238 static struct timeval otv;
2240 gettimeofday(&tv, NULL);
2242 if (otv.tv_sec == 0)
2244 tv_sub(&dtv, &tv, &otv);
2245 tprintf("%6ld.%06ld ",
2246 (long) dtv.tv_sec, (long) dtv.tv_usec);
2249 else if (tflag > 2) {
2250 tprintf("%ld.%06ld ",
2251 (long) tv.tv_sec, (long) tv.tv_usec);
2254 time_t local = tv.tv_sec;
2255 strftime(str, sizeof(str), "%T", localtime(&local));
2257 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
2259 tprintf("%s ", str);
2271 tprintf("%*s", col - curcol, "");
2282 #ifdef HAVE_MP_PROCFS
2284 int mp_ioctl (int fd, int cmd, void *arg, int size) {
2286 struct iovec iov[2];
2289 iov[0].iov_base = &cmd;
2290 iov[0].iov_len = sizeof cmd;
2293 iov[1].iov_base = arg;
2294 iov[1].iov_len = size;
2297 return writev (fd, iov, n);