strace.c revision eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152
1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id$ 31 */ 32 33#include <sys/types.h> 34#include "defs.h" 35 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 48#if defined(IA64) && defined(LINUX) 49# include <asm/ptrace_offsets.h> 50#endif 51 52#ifdef USE_PROCFS 53#include <poll.h> 54#endif 55 56#ifdef SVR4 57#include <sys/stropts.h> 58#ifdef HAVE_MP_PROCFS 59#ifdef HAVE_SYS_UIO_H 60#include <sys/uio.h> 61#endif 62#endif 63#endif 64 65int debug = 0, followfork = 0, followvfork = 0, interactive = 0; 66int rflag = 0, tflag = 0, dtime = 0, cflag = 0; 67int iflag = 0, xflag = 0, qflag = 0; 68int pflag_seen = 0; 69 70char *username = NULL; 71uid_t run_uid; 72gid_t run_gid; 73 74int acolumn = DEFAULT_ACOLUMN; 75int max_strlen = DEFAULT_STRLEN; 76char *outfname = NULL; 77FILE *outf; 78struct tcb tcbtab[MAX_PROCS]; 79int nprocs; 80char *progname; 81extern char version[]; 82extern char **environ; 83 84static struct tcb *pid2tcb P((int pid)); 85static int trace P((void)); 86static void cleanup P((void)); 87static void interrupt P((int sig)); 88static sigset_t empty_set, blocked_set; 89 90#ifdef HAVE_SIG_ATOMIC_T 91static volatile sig_atomic_t interrupted; 92#else /* !HAVE_SIG_ATOMIC_T */ 93#ifdef __STDC__ 94static volatile int interrupted; 95#else /* !__STDC__ */ 96static int interrupted; 97#endif /* !__STDC__ */ 98#endif /* !HAVE_SIG_ATOMIC_T */ 99 100#ifdef USE_PROCFS 101 102static struct tcb *pfd2tcb P((int pfd)); 103static void reaper P((int sig)); 104static void rebuild_pollv P((void)); 105struct pollfd pollv[MAX_PROCS]; 106 107#ifndef HAVE_POLLABLE_PROCFS 108 109static void proc_poll_open P((void)); 110static void proc_poller P((int pfd)); 111 112struct proc_pollfd { 113 int fd; 114 int revents; 115 int pid; 116}; 117 118static int poller_pid; 119static int proc_poll_pipe[2] = { -1, -1 }; 120 121#endif /* !HAVE_POLLABLE_PROCFS */ 122 123#ifdef HAVE_MP_PROCFS 124#define POLLWANT POLLWRNORM 125#else 126#define POLLWANT POLLPRI 127#endif 128#endif /* USE_PROCFS */ 129 130static void 131usage(ofp, exitval) 132FILE *ofp; 133int exitval; 134{ 135 fprintf(ofp, "\ 136usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ 137 [-p pid] ... [-s strsize] [-u username] [command [arg ...]]\n\ 138 or: strace -c [-e expr] ... [-O overhead] [-S sortby] [command [arg ...]]\n\ 139-c -- count time, calls, and errors for each syscall and report summary\n\ 140-f -- follow forks, -ff -- with output into separate files\n\ 141-F -- attempt to follow vforks, -h -- print help message\n\ 142-i -- print instruction pointer at time of syscall\n\ 143-q -- suppress messages about attaching, detaching, etc.\n\ 144-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 145-T -- print time spent in each syscall, -V -- print version\n\ 146-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 147-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 148-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 149-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 150 options: trace, abbrev, verbose, raw, signal, read, or write\n\ 151-o file -- send trace output to FILE instead of stderr\n\ 152-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 153-p pid -- trace process with process id PID, may be repeated\n\ 154-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 155-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 156-u username -- run command as username handling setuid and/or setgid\n\ 157", DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 158 exit(exitval); 159} 160 161#ifdef SVR4 162#ifdef MIPS 163void 164foobar() 165{ 166} 167#endif /* MIPS */ 168#endif /* SVR4 */ 169 170int 171main(argc, argv) 172int argc; 173char *argv[]; 174{ 175 extern int optind; 176 extern char *optarg; 177 struct tcb *tcp; 178 int c, pid = 0; 179 struct sigaction sa; 180 181 static char buf[BUFSIZ]; 182 183 progname = argv[0]; 184 outf = stderr; 185 interactive = 1; 186 qualify("trace=all"); 187 qualify("abbrev=all"); 188 qualify("verbose=all"); 189 qualify("signal=all"); 190 set_sortby(DEFAULT_SORTBY); 191 set_personality(DEFAULT_PERSONALITY); 192 while ((c = getopt(argc, argv, 193 "+cdfFhiqrtTvVxa:e:o:O:p:s:S:u:")) != EOF) { 194 switch (c) { 195 case 'c': 196 cflag++; 197 dtime++; 198 break; 199 case 'd': 200 debug++; 201 break; 202 case 'f': 203 followfork++; 204 break; 205 case 'F': 206 followvfork++; 207 break; 208 case 'h': 209 usage(stdout, 0); 210 break; 211 case 'i': 212 iflag++; 213 break; 214 case 'q': 215 qflag++; 216 break; 217 case 'r': 218 rflag++; 219 tflag++; 220 break; 221 case 't': 222 tflag++; 223 break; 224 case 'T': 225 dtime++; 226 break; 227 case 'x': 228 xflag++; 229 break; 230 case 'v': 231 qualify("abbrev=none"); 232 break; 233 case 'V': 234 printf("%s\n", version); 235 exit(0); 236 break; 237 case 'a': 238 acolumn = atoi(optarg); 239 break; 240 case 'e': 241 qualify(optarg); 242 break; 243 case 'o': 244 outfname = strdup(optarg); 245 break; 246 case 'O': 247 set_overhead(atoi(optarg)); 248 break; 249 case 'p': 250 if ((pid = atoi(optarg)) == 0) { 251 fprintf(stderr, "%s: Invalid process id: %s\n", 252 progname, optarg); 253 break; 254 } 255 if (pid == getpid()) { 256 fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname); 257 break; 258 } 259 if ((tcp = alloctcb(pid)) == NULL) { 260 fprintf(stderr, "%s: tcb table full, please recompile strace\n", 261 progname); 262 exit(1); 263 } 264 tcp->flags |= TCB_ATTACHED; 265 pflag_seen++; 266 break; 267 case 's': 268 max_strlen = atoi(optarg); 269 break; 270 case 'S': 271 set_sortby(optarg); 272 break; 273 case 'u': 274 username = strdup(optarg); 275 break; 276 default: 277 usage(stderr, 1); 278 break; 279 } 280 } 281 282 /* See if they want to run as another user. */ 283 if (username != NULL) { 284 struct passwd *pent; 285 286 if (getuid() != 0 || geteuid() != 0) { 287 fprintf(stderr, 288 "%s: you must be root to use the -u option\n", 289 progname); 290 exit(1); 291 } 292 if ((pent = getpwnam(username)) == NULL) { 293 fprintf(stderr, "%s: cannot find user `%s'\n", 294 progname, optarg); 295 exit(1); 296 } 297 run_uid = pent->pw_uid; 298 run_gid = pent->pw_gid; 299 } 300 else { 301 run_uid = getuid(); 302 run_gid = getgid(); 303 } 304 305#ifndef SVR4 306 setreuid(geteuid(), getuid()); 307#endif 308 309 /* See if they want to pipe the output. */ 310 if (outfname && (outfname[0] == '|' || outfname[0] == '!')) { 311 if ((outf = popen(outfname + 1, "w")) == NULL) { 312 fprintf(stderr, "%s: can't popen '%s': %s\n", 313 progname, outfname + 1, strerror(errno)); 314 exit(1); 315 } 316 free(outfname); 317 outfname = NULL; 318 } 319 320 /* Check if they want to redirect the output. */ 321 if (outfname) { 322 long f; 323 324 if ((outf = fopen(outfname, "w")) == NULL) { 325 fprintf(stderr, "%s: can't fopen '%s': %s\n", 326 progname, outfname, strerror(errno)); 327 exit(1); 328 } 329 330 if ((f=fcntl(fileno(outf), F_GETFD)) < 0 ) { 331 perror("failed to get flags for outputfile"); 332 exit(1); 333 } 334 335 if (fcntl(fileno(outf), F_SETFD, f|FD_CLOEXEC) < 0 ) { 336 perror("failed to set flags for outputfile"); 337 exit(1); 338 } 339 } 340 341#ifndef SVR4 342 setreuid(geteuid(), getuid()); 343#endif 344 345 if (!outfname) { 346 qflag = 1; 347 setvbuf(outf, buf, _IOLBF, BUFSIZ); 348 } 349 else if (optind < argc) 350 interactive = 0; 351 else 352 qflag = 1; 353 354 for (c = 0, tcp = tcbtab; c < MAX_PROCS; c++, tcp++) { 355 /* Reinitialize the output since it may have changed. */ 356 tcp->outf = outf; 357 if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 358 continue; 359#ifdef USE_PROCFS 360 if (proc_open(tcp, 1) < 0) { 361 fprintf(stderr, "trouble opening proc file\n"); 362 droptcb(tcp); 363 continue; 364 } 365#else /* !USE_PROCFS */ 366 if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 367 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 368 droptcb(tcp); 369 continue; 370 } 371#endif /* !USE_PROCFS */ 372 if (!qflag) 373 fprintf(stderr, 374 "Process %u attached - interrupt to quit\n", 375 pid); 376 } 377 378 if (optind < argc) { 379 struct stat statbuf; 380 char *filename; 381 char pathname[MAXPATHLEN]; 382 383 filename = argv[optind]; 384 if (strchr(filename, '/')) 385 strcpy(pathname, filename); 386#ifdef USE_DEBUGGING_EXEC 387 /* 388 * Debuggers customarily check the current directory 389 * first regardless of the path but doing that gives 390 * security geeks a panic attack. 391 */ 392 else if (stat(filename, &statbuf) == 0) 393 strcpy(pathname, filename); 394#endif /* USE_DEBUGGING_EXEC */ 395 else { 396 char *path; 397 int m, n, len; 398 399 for (path = getenv("PATH"); path && *path; path += m) { 400 if (strchr(path, ':')) { 401 n = strchr(path, ':') - path; 402 m = n + 1; 403 } 404 else 405 m = n = strlen(path); 406 if (n == 0) { 407 getcwd(pathname, MAXPATHLEN); 408 len = strlen(pathname); 409 } 410 else { 411 strncpy(pathname, path, n); 412 len = n; 413 } 414 if (len && pathname[len - 1] != '/') 415 pathname[len++] = '/'; 416 strcpy(pathname + len, filename); 417 if (stat(pathname, &statbuf) == 0) 418 break; 419 } 420 } 421 if (stat(pathname, &statbuf) < 0) { 422 fprintf(stderr, "%s: %s: command not found\n", 423 progname, filename); 424 exit(1); 425 } 426 switch (pid = fork()) { 427 case -1: 428 perror("strace: fork"); 429 cleanup(); 430 exit(1); 431 break; 432 case 0: { 433#ifdef USE_PROCFS 434 if (outf != stderr) close (fileno (outf)); 435#ifdef MIPS 436 /* Kludge for SGI, see proc_open for details. */ 437 sa.sa_handler = foobar; 438 sa.sa_flags = 0; 439 sigemptyset(&sa.sa_mask); 440 sigaction(SIGINT, &sa, NULL); 441#endif /* MIPS */ 442#ifndef FREEBSD 443 pause(); 444#else /* FREEBSD */ 445 kill(getpid(), SIGSTOP); /* stop HERE */ 446#endif /* FREEBSD */ 447#else /* !USE_PROCFS */ 448 if (outf!=stderr) 449 close(fileno (outf)); 450 451 if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 452 perror("strace: ptrace(PTRACE_TRACEME, ...)"); 453 return -1; 454 } 455 if (debug) 456 kill(getpid(), SIGSTOP); 457 458 if (username != NULL || geteuid() == 0) { 459 uid_t run_euid = run_uid; 460 gid_t run_egid = run_gid; 461 462 if (statbuf.st_mode & S_ISUID) 463 run_euid = statbuf.st_uid; 464 if (statbuf.st_mode & S_ISGID) 465 run_egid = statbuf.st_gid; 466 467 /* 468 * It is important to set groups before we 469 * lose privileges on setuid. 470 */ 471 if (username != NULL) { 472 if (initgroups(username, run_gid) < 0) { 473 perror("initgroups"); 474 exit(1); 475 } 476 if (setregid(run_gid, run_egid) < 0) { 477 perror("setregid"); 478 exit(1); 479 } 480 if (setreuid(run_uid, run_euid) < 0) { 481 perror("setreuid"); 482 exit(1); 483 } 484 } 485 } 486 else 487 setreuid(run_uid, run_uid); 488#endif /* !USE_PROCFS */ 489 490 execv(pathname, &argv[optind]); 491 perror("strace: exec"); 492 _exit(1); 493 break; 494 } 495 default: 496 if ((tcp = alloctcb(pid)) == NULL) { 497 fprintf(stderr, "tcb table full\n"); 498 cleanup(); 499 exit(1); 500 } 501#ifdef USE_PROCFS 502 if (proc_open(tcp, 0) < 0) { 503 fprintf(stderr, "trouble opening proc file\n"); 504 cleanup(); 505 exit(1); 506 } 507#endif /* USE_PROCFS */ 508#ifndef USE_PROCFS 509 fake_execve(tcp, pathname, &argv[optind], environ); 510#endif /* !USE_PROCFS */ 511 break; 512 } 513 } 514 else if (pflag_seen == 0) 515 usage(stderr, 1); 516 517 sigemptyset(&empty_set); 518 sigemptyset(&blocked_set); 519 sa.sa_handler = SIG_IGN; 520 sigemptyset(&sa.sa_mask); 521 sa.sa_flags = 0; 522 sigaction(SIGTTOU, &sa, NULL); 523 sigaction(SIGTTIN, &sa, NULL); 524 if (interactive) { 525 sigaddset(&blocked_set, SIGHUP); 526 sigaddset(&blocked_set, SIGINT); 527 sigaddset(&blocked_set, SIGQUIT); 528 sigaddset(&blocked_set, SIGPIPE); 529 sigaddset(&blocked_set, SIGTERM); 530 sa.sa_handler = interrupt; 531#ifdef SUNOS4 532 /* POSIX signals on sunos4.1 are a little broken. */ 533 sa.sa_flags = SA_INTERRUPT; 534#endif /* SUNOS4 */ 535 } 536 sigaction(SIGHUP, &sa, NULL); 537 sigaction(SIGINT, &sa, NULL); 538 sigaction(SIGQUIT, &sa, NULL); 539 sigaction(SIGPIPE, &sa, NULL); 540 sigaction(SIGTERM, &sa, NULL); 541#ifdef USE_PROCFS 542 sa.sa_handler = reaper; 543 sigaction(SIGCHLD, &sa, NULL); 544#endif /* USE_PROCFS */ 545 546 if (trace() < 0) 547 exit(1); 548 cleanup(); 549 exit(0); 550} 551 552void 553newoutf(tcp) 554struct tcb *tcp; 555{ 556 char name[MAXPATHLEN]; 557 FILE *fp; 558 559 if (outfname && followfork > 1) { 560 sprintf(name, "%s.%u", outfname, tcp->pid); 561#ifndef SVR4 562 setreuid(geteuid(), getuid()); 563#endif 564 fp = fopen(name, "w"); 565#ifndef SVR4 566 setreuid(geteuid(), getuid()); 567#endif 568 if (fp == NULL) { 569 perror("fopen"); 570 return; 571 } 572 tcp->outf = fp; 573 } 574 return; 575} 576 577struct tcb * 578alloctcb(pid) 579int pid; 580{ 581 int i; 582 struct tcb *tcp; 583 584 for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) { 585 if ((tcp->flags & TCB_INUSE) == 0) { 586 tcp->pid = pid; 587 tcp->parent = NULL; 588 tcp->nchildren = 0; 589 tcp->flags = TCB_INUSE | TCB_STARTUP; 590 tcp->outf = outf; /* Initialise to current out file */ 591 tcp->stime.tv_sec = 0; 592 tcp->stime.tv_usec = 0; 593 tcp->pfd = -1; 594 nprocs++; 595 return tcp; 596 } 597 } 598 return NULL; 599} 600 601#ifdef USE_PROCFS 602int 603proc_open(tcp, attaching) 604struct tcb *tcp; 605int attaching; 606{ 607 char proc[32]; 608 long arg; 609#ifdef SVR4 610 int i; 611 sysset_t syscalls; 612 sigset_t signals; 613 fltset_t faults; 614#endif 615#ifndef HAVE_POLLABLE_PROCFS 616 static int last_pfd; 617#endif 618 619#ifdef HAVE_MP_PROCFS 620 /* Open the process pseudo-files in /proc. */ 621 sprintf(proc, "/proc/%d/ctl", tcp->pid); 622 if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 623 perror("strace: open(\"/proc/...\", ...)"); 624 return -1; 625 } 626 if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 627 perror("F_GETFD"); 628 return -1; 629 } 630 if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 631 perror("F_SETFD"); 632 return -1; 633 } 634 sprintf(proc, "/proc/%d/status", tcp->pid); 635 if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 636 perror("strace: open(\"/proc/...\", ...)"); 637 return -1; 638 } 639 if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) { 640 perror("F_GETFD"); 641 return -1; 642 } 643 if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) { 644 perror("F_SETFD"); 645 return -1; 646 } 647 sprintf(proc, "/proc/%d/as", tcp->pid); 648 if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 649 perror("strace: open(\"/proc/...\", ...)"); 650 return -1; 651 } 652 if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) { 653 perror("F_GETFD"); 654 return -1; 655 } 656 if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) { 657 perror("F_SETFD"); 658 return -1; 659 } 660#else 661 /* Open the process pseudo-file in /proc. */ 662#ifndef FREEBSD 663 sprintf(proc, "/proc/%d", tcp->pid); 664 if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) { 665#else /* FREEBSD */ 666 sprintf(proc, "/proc/%d/mem", tcp->pid); 667 if ((tcp->pfd = open(proc, O_RDWR)) < 0) { 668#endif /* FREEBSD */ 669 perror("strace: open(\"/proc/...\", ...)"); 670 return -1; 671 } 672 if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 673 perror("F_GETFD"); 674 return -1; 675 } 676 if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 677 perror("F_SETFD"); 678 return -1; 679 } 680#endif 681#ifdef FREEBSD 682 sprintf(proc, "/proc/%d/regs", tcp->pid); 683 if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 684 perror("strace: open(\"/proc/.../regs\", ...)"); 685 return -1; 686 } 687 if (cflag) { 688 sprintf(proc, "/proc/%d/status", tcp->pid); 689 if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 690 perror("strace: open(\"/proc/.../status\", ...)"); 691 return -1; 692 } 693 } else 694 tcp->pfd_status = -1; 695#endif /* FREEBSD */ 696 rebuild_pollv(); 697 if (!attaching) { 698 /* 699 * Wait for the child to pause. Because of a race 700 * condition we have to poll for the event. 701 */ 702 for (;;) { 703 if (IOCTL_STATUS (tcp) < 0) { 704 perror("strace: PIOCSTATUS"); 705 return -1; 706 } 707 if (tcp->status.PR_FLAGS & PR_ASLEEP) 708 break; 709 } 710 } 711#ifndef FREEBSD 712 /* Stop the process so that we own the stop. */ 713 if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 714 perror("strace: PIOCSTOP"); 715 return -1; 716 } 717#endif 718#ifdef PIOCSET 719 /* Set Run-on-Last-Close. */ 720 arg = PR_RLC; 721 if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 722 perror("PIOCSET PR_RLC"); 723 return -1; 724 } 725 /* Set or Reset Inherit-on-Fork. */ 726 arg = PR_FORK; 727 if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 728 perror("PIOC{SET,RESET} PR_FORK"); 729 return -1; 730 } 731#else /* !PIOCSET */ 732#ifndef FREEBSD 733 if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 734 perror("PIOCSRLC"); 735 return -1; 736 } 737 if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 738 perror("PIOC{S,R}FORK"); 739 return -1; 740 } 741#else /* FREEBSD */ 742 /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 743 if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 744 perror("PIOCGFL"); 745 return -1; 746 } 747 arg &= ~PF_LINGER; 748 if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 749 perror("PIOCSFL"); 750 return -1; 751 } 752#endif /* FREEBSD */ 753#endif /* !PIOCSET */ 754#ifndef FREEBSD 755 /* Enable all syscall entries we care about. */ 756 premptyset(&syscalls); 757 for (i = 1; i < MAX_QUALS; ++i) { 758 if (i > (sizeof syscalls) * CHAR_BIT) break; 759 if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i); 760 } 761 praddset (&syscalls, SYS_execve); 762 if (followfork) { 763 praddset (&syscalls, SYS_fork); 764#ifdef SYS_forkall 765 praddset (&syscalls, SYS_forkall); 766#endif 767#ifdef SYS_fork1 768 praddset (&syscalls, SYS_fork1); 769#endif 770#ifdef SYS_rfork1 771 praddset (&syscalls, SYS_rfork1); 772#endif 773#ifdef SYS_rforkall 774 praddset (&syscalls, SYS_rforkall); 775#endif 776 } 777 if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 778 perror("PIOCSENTRY"); 779 return -1; 780 } 781 /* Enable the syscall exits. */ 782 if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 783 perror("PIOSEXIT"); 784 return -1; 785 } 786 /* Enable signals we care about. */ 787 premptyset(&signals); 788 for (i = 1; i < MAX_QUALS; ++i) { 789 if (i > (sizeof signals) * CHAR_BIT) break; 790 if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i); 791 } 792 if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 793 perror("PIOCSTRACE"); 794 return -1; 795 } 796 /* Enable faults we care about */ 797 premptyset(&faults); 798 for (i = 1; i < MAX_QUALS; ++i) { 799 if (i > (sizeof faults) * CHAR_BIT) break; 800 if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i); 801 } 802 if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 803 perror("PIOCSFAULT"); 804 return -1; 805 } 806#else /* FREEBSD */ 807 /* set events flags. */ 808 arg = S_SIG | S_SCE | S_SCX ; 809 if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 810 perror("PIOCBIS"); 811 return -1; 812 } 813#endif /* FREEBSD */ 814 if (!attaching) { 815#ifdef MIPS 816 /* 817 * The SGI PRSABORT doesn't work for pause() so 818 * we send it a caught signal to wake it up. 819 */ 820 kill(tcp->pid, SIGINT); 821#else /* !MIPS */ 822#ifdef PRSABORT 823 /* The child is in a pause(), abort it. */ 824 arg = PRSABORT; 825 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 826 perror("PIOCRUN"); 827 return -1; 828 } 829#endif 830#endif /* !MIPS*/ 831#ifdef FREEBSD 832 /* wake up the child if it received the SIGSTOP */ 833 kill(tcp->pid, SIGCONT); 834#endif 835 for (;;) { 836 /* Wait for the child to do something. */ 837 if (IOCTL_WSTOP (tcp) < 0) { 838 perror("PIOCWSTOP"); 839 return -1; 840 } 841 if (tcp->status.PR_WHY == PR_SYSENTRY) { 842 tcp->flags &= ~TCB_INSYSCALL; 843 get_scno(tcp); 844 if (tcp->scno == SYS_execve) 845 break; 846 } 847 /* Set it running: maybe execve will be next. */ 848#ifndef FREEBSD 849 arg = 0; 850 if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 851#else /* FREEBSD */ 852 if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 853#endif /* FREEBSD */ 854 perror("PIOCRUN"); 855 return -1; 856 } 857#ifdef FREEBSD 858 /* handle the case where we "opened" the child before 859 it did the kill -STOP */ 860 if (tcp->status.PR_WHY == PR_SIGNALLED && 861 tcp->status.PR_WHAT == SIGSTOP) 862 kill(tcp->pid, SIGCONT); 863#endif 864 } 865#ifndef FREEBSD 866 } 867#else /* FREEBSD */ 868 } else { 869 if (attaching < 2) { 870 /* We are attaching to an already running process. 871 * Try to figure out the state of the process in syscalls, 872 * to handle the first event well. 873 * This is done by having a look at the "wchan" property of the 874 * process, which tells where it is stopped (if it is). */ 875 FILE * status; 876 char wchan[20]; /* should be enough */ 877 878 sprintf(proc, "/proc/%d/status", tcp->pid); 879 status = fopen(proc, "r"); 880 if (status && 881 (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 882 "%*d,%*d %*d,%*d %19s", wchan) == 1) && 883 strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 884 strcmp(wchan, "stopevent")) { 885 /* The process is asleep in the middle of a syscall. 886 Fake the syscall entry event */ 887 tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 888 tcp->status.PR_WHY = PR_SYSENTRY; 889 trace_syscall(tcp); 890 } 891 if (status) 892 fclose(status); 893 } /* otherwise it's a fork being followed */ 894 } 895#endif /* FREEBSD */ 896#ifndef HAVE_POLLABLE_PROCFS 897 if (proc_poll_pipe[0] != -1) 898 proc_poller(tcp->pfd); 899 else if (nprocs > 1) { 900 proc_poll_open(); 901 proc_poller(last_pfd); 902 proc_poller(tcp->pfd); 903 } 904 last_pfd = tcp->pfd; 905#endif /* !HAVE_POLLABLE_PROCFS */ 906 return 0; 907} 908 909#endif /* USE_PROCFS */ 910 911static struct tcb * 912pid2tcb(pid) 913int pid; 914{ 915 int i; 916 struct tcb *tcp; 917 918 for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) { 919 if (pid && tcp->pid != pid) 920 continue; 921 if (tcp->flags & TCB_INUSE) 922 return tcp; 923 } 924 return NULL; 925} 926 927#ifdef USE_PROCFS 928 929static struct tcb * 930pfd2tcb(pfd) 931int pfd; 932{ 933 int i; 934 struct tcb *tcp; 935 936 for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) { 937 if (tcp->pfd != pfd) 938 continue; 939 if (tcp->flags & TCB_INUSE) 940 return tcp; 941 } 942 return NULL; 943} 944 945#endif /* USE_PROCFS */ 946 947void 948droptcb(tcp) 949struct tcb *tcp; 950{ 951 if (tcp->pid == 0) 952 return; 953 nprocs--; 954 tcp->pid = 0; 955 tcp->flags = 0; 956 957 if (tcp->pfd != -1) { 958 close(tcp->pfd); 959 tcp->pfd = -1; 960#ifdef FREEBSD 961 if (tcp->pfd_reg != -1) { 962 close(tcp->pfd_reg); 963 tcp->pfd_reg = -1; 964 } 965 if (tcp->pfd_status != -1) { 966 close(tcp->pfd_status); 967 tcp->pfd_status = -1; 968 } 969#endif /* !FREEBSD */ 970#ifdef USE_PROCFS 971 rebuild_pollv(); 972#endif 973 } 974 if (tcp->parent != NULL) { 975 tcp->parent->nchildren--; 976 tcp->parent = NULL; 977 } 978 979 if (outfname && tcp->outf) 980 fclose(tcp->outf); 981 982 tcp->outf = 0; 983} 984 985#ifndef USE_PROCFS 986 987static int 988resume(tcp) 989struct tcb *tcp; 990{ 991 if (tcp == NULL) 992 return -1; 993 994 if (!(tcp->flags & TCB_SUSPENDED)) { 995 fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid); 996 return -1; 997 } 998 tcp->flags &= ~TCB_SUSPENDED; 999 1000 if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) { 1001 perror("resume: ptrace(PTRACE_SYSCALL, ...)"); 1002 return -1; 1003 } 1004 1005 if (!qflag) 1006 fprintf(stderr, "Process %u resumed\n", tcp->pid); 1007 return 0; 1008} 1009 1010#endif /* !USE_PROCFS */ 1011 1012/* detach traced process; continue with sig */ 1013 1014static int 1015detach(tcp, sig) 1016struct tcb *tcp; 1017int sig; 1018{ 1019 int error = 0; 1020#ifdef LINUX 1021 int status; 1022#endif 1023 1024 if (tcp->flags & TCB_BPTSET) 1025 sig = SIGKILL; 1026 1027#ifdef LINUX 1028 /* 1029 * Linux wrongly insists the child be stopped 1030 * before detaching. Arghh. We go through hoops 1031 * to make a clean break of things. 1032 */ 1033#if defined(SPARC) 1034#undef PTRACE_DETACH 1035#define PTRACE_DETACH PTRACE_SUNDETACH 1036#endif 1037 if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 1038 /* On a clear day, you can see forever. */ 1039 } 1040 else if (errno != ESRCH) { 1041 /* Shouldn't happen. */ 1042 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1043 } 1044 else if (kill(tcp->pid, 0) < 0) { 1045 if (errno != ESRCH) 1046 perror("detach: checking sanity"); 1047 } 1048 else if (kill(tcp->pid, SIGSTOP) < 0) { 1049 if (errno != ESRCH) 1050 perror("detach: stopping child"); 1051 } 1052 else { 1053 for (;;) { 1054 if (waitpid(tcp->pid, &status, 0) < 0) { 1055 if (errno != ECHILD) 1056 perror("detach: waiting"); 1057 break; 1058 } 1059 if (!WIFSTOPPED(status)) { 1060 /* Au revoir, mon ami. */ 1061 break; 1062 } 1063 if (WSTOPSIG(status) == SIGSTOP) { 1064 if ((error = ptrace(PTRACE_DETACH, 1065 tcp->pid, (char *) 1, sig)) < 0) { 1066 if (errno != ESRCH) 1067 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1068 /* I died trying. */ 1069 } 1070 break; 1071 } 1072 if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1, 1073 WSTOPSIG(status) == SIGTRAP ? 1074 0 : WSTOPSIG(status))) < 0) { 1075 if (errno != ESRCH) 1076 perror("detach: ptrace(PTRACE_CONT, ...)"); 1077 break; 1078 } 1079 } 1080 } 1081#endif /* LINUX */ 1082 1083#if defined(SUNOS4) 1084 /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 1085 if (sig && kill(tcp->pid, sig) < 0) 1086 perror("detach: kill"); 1087 sig = 0; 1088 if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0) 1089 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1090#endif /* SUNOS4 */ 1091 1092#ifndef USE_PROCFS 1093 if (waiting_parent(tcp)) 1094 error = resume(tcp->parent); 1095#endif /* !USE_PROCFS */ 1096 1097 if (!qflag) 1098 fprintf(stderr, "Process %u detached\n", tcp->pid); 1099 1100 droptcb(tcp); 1101 return error; 1102} 1103 1104#ifdef USE_PROCFS 1105 1106static void 1107reaper(sig) 1108int sig; 1109{ 1110 int pid; 1111 int status; 1112 1113 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 1114#if 0 1115 struct tcb *tcp; 1116 1117 tcp = pid2tcb(pid); 1118 if (tcp) 1119 droptcb(tcp); 1120#endif 1121 } 1122} 1123 1124#endif /* USE_PROCFS */ 1125 1126static void 1127cleanup() 1128{ 1129 int i; 1130 struct tcb *tcp; 1131 1132 for (i = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) { 1133 if (!(tcp->flags & TCB_INUSE)) 1134 continue; 1135 if (debug) 1136 fprintf(stderr, 1137 "cleanup: looking at pid %u\n", tcp->pid); 1138 if (tcp_last && 1139 (!outfname || followfork < 2 || tcp_last == tcp)) { 1140 tprintf(" <unfinished ...>\n"); 1141 tcp_last = NULL; 1142 } 1143 if (tcp->flags & TCB_ATTACHED) 1144 detach(tcp, 0); 1145 else { 1146 kill(tcp->pid, SIGCONT); 1147 kill(tcp->pid, SIGTERM); 1148 } 1149 } 1150 if (cflag) 1151 call_summary(outf); 1152} 1153 1154static void 1155interrupt(sig) 1156int sig; 1157{ 1158 interrupted = 1; 1159} 1160 1161#ifndef HAVE_STRERROR 1162 1163#ifndef SYS_ERRLIST_DECLARED 1164extern int sys_nerr; 1165extern char *sys_errlist[]; 1166#endif /* SYS_ERRLIST_DECLARED */ 1167 1168const char * 1169strerror(errno) 1170int errno; 1171{ 1172 static char buf[64]; 1173 1174 if (errno < 1 || errno >= sys_nerr) { 1175 sprintf(buf, "Unknown error %d", errno); 1176 return buf; 1177 } 1178 return sys_errlist[errno]; 1179} 1180 1181#endif /* HAVE_STERRROR */ 1182 1183#ifndef HAVE_STRSIGNAL 1184 1185#ifndef SYS_SIGLIST_DECLARED 1186#ifdef HAVE__SYS_SIGLIST 1187 extern char *_sys_siglist[]; 1188#else 1189 extern char *sys_siglist[]; 1190#endif 1191#endif /* SYS_SIGLIST_DECLARED */ 1192 1193const char * 1194strsignal(sig) 1195int sig; 1196{ 1197 static char buf[64]; 1198 1199 if (sig < 1 || sig >= NSIG) { 1200 sprintf(buf, "Unknown signal %d", sig); 1201 return buf; 1202 } 1203#ifdef HAVE__SYS_SIGLIST 1204 return _sys_siglist[sig]; 1205#else 1206 return sys_siglist[sig]; 1207#endif 1208} 1209 1210#endif /* HAVE_STRSIGNAL */ 1211 1212#ifdef USE_PROCFS 1213 1214static void 1215rebuild_pollv() 1216{ 1217 int i, j; 1218 struct tcb *tcp; 1219 1220 for (i = j = 0, tcp = tcbtab; i < MAX_PROCS; i++, tcp++) { 1221 if (!(tcp->flags & TCB_INUSE)) 1222 continue; 1223 pollv[j].fd = tcp->pfd; 1224 pollv[j].events = POLLWANT; 1225 j++; 1226 } 1227 if (j != nprocs) { 1228 fprintf(stderr, "strace: proc miscount\n"); 1229 exit(1); 1230 } 1231} 1232 1233#ifndef HAVE_POLLABLE_PROCFS 1234 1235static void 1236proc_poll_open() 1237{ 1238 int arg; 1239 int i; 1240 1241 if (pipe(proc_poll_pipe) < 0) { 1242 perror("pipe"); 1243 exit(1); 1244 } 1245 for (i = 0; i < 2; i++) { 1246 if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) { 1247 perror("F_GETFD"); 1248 exit(1); 1249 } 1250 if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) { 1251 perror("F_SETFD"); 1252 exit(1); 1253 } 1254 } 1255} 1256 1257static int 1258proc_poll(pollv, nfds, timeout) 1259struct pollfd *pollv; 1260int nfds; 1261int timeout; 1262{ 1263 int i; 1264 int n; 1265 struct proc_pollfd pollinfo; 1266 1267 if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 1268 return n; 1269 if (n != sizeof(struct proc_pollfd)) { 1270 fprintf(stderr, "panic: short read: %d\n", n); 1271 exit(1); 1272 } 1273 for (i = 0; i < nprocs; i++) { 1274 if (pollv[i].fd == pollinfo.fd) 1275 pollv[i].revents = pollinfo.revents; 1276 else 1277 pollv[i].revents = 0; 1278 } 1279 poller_pid = pollinfo.pid; 1280 return 1; 1281} 1282 1283static void 1284wakeup_handler(sig) 1285int sig; 1286{ 1287} 1288 1289static void 1290proc_poller(pfd) 1291int pfd; 1292{ 1293 struct proc_pollfd pollinfo; 1294 struct sigaction sa; 1295 sigset_t blocked_set, empty_set; 1296 int i; 1297 int n; 1298 struct rlimit rl; 1299#ifdef FREEBSD 1300 struct procfs_status pfs; 1301#endif /* FREEBSD */ 1302 1303 switch (fork()) { 1304 case -1: 1305 perror("fork"); 1306 _exit(0); 1307 case 0: 1308 break; 1309 default: 1310 return; 1311 } 1312 1313 sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 1314 sa.sa_flags = 0; 1315 sigemptyset(&sa.sa_mask); 1316 sigaction(SIGHUP, &sa, NULL); 1317 sigaction(SIGINT, &sa, NULL); 1318 sigaction(SIGQUIT, &sa, NULL); 1319 sigaction(SIGPIPE, &sa, NULL); 1320 sigaction(SIGTERM, &sa, NULL); 1321 sa.sa_handler = wakeup_handler; 1322 sigaction(SIGUSR1, &sa, NULL); 1323 sigemptyset(&blocked_set); 1324 sigaddset(&blocked_set, SIGUSR1); 1325 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1326 sigemptyset(&empty_set); 1327 1328 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 1329 perror("getrlimit(RLIMIT_NOFILE, ...)"); 1330 _exit(0); 1331 } 1332 n = rl.rlim_cur; 1333 for (i = 0; i < n; i++) { 1334 if (i != pfd && i != proc_poll_pipe[1]) 1335 close(i); 1336 } 1337 1338 pollinfo.fd = pfd; 1339 pollinfo.pid = getpid(); 1340 for (;;) { 1341#ifndef FREEBSD 1342 if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 1343#else /* FREEBSD */ 1344 if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 1345#endif /* FREEBSD */ 1346 { 1347 switch (errno) { 1348 case EINTR: 1349 continue; 1350 case EBADF: 1351 pollinfo.revents = POLLERR; 1352 break; 1353 case ENOENT: 1354 pollinfo.revents = POLLHUP; 1355 break; 1356 default: 1357 perror("proc_poller: PIOCWSTOP"); 1358 } 1359 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 1360 _exit(0); 1361 } 1362 pollinfo.revents = POLLWANT; 1363 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 1364 sigsuspend(&empty_set); 1365 } 1366} 1367 1368#endif /* !HAVE_POLLABLE_PROCFS */ 1369 1370static int 1371choose_pfd() 1372{ 1373 int i, j; 1374 struct tcb *tcp; 1375 1376 static int last; 1377 1378 if (followfork < 2 && 1379 last < nprocs && (pollv[last].revents & POLLWANT)) { 1380 /* 1381 * The previous process is ready to run again. We'll 1382 * let it do so if it is currently in a syscall. This 1383 * heuristic improves the readability of the trace. 1384 */ 1385 tcp = pfd2tcb(pollv[last].fd); 1386 if (tcp && (tcp->flags & TCB_INSYSCALL)) 1387 return pollv[last].fd; 1388 } 1389 1390 for (i = 0; i < nprocs; i++) { 1391 /* Let competing children run round robin. */ 1392 j = (i + last + 1) % nprocs; 1393 if (pollv[j].revents & (POLLHUP | POLLERR)) { 1394 tcp = pfd2tcb(pollv[j].fd); 1395 if (!tcp) { 1396 fprintf(stderr, "strace: lost proc\n"); 1397 exit(1); 1398 } 1399 droptcb(tcp); 1400 return -1; 1401 } 1402 if (pollv[j].revents & POLLWANT) { 1403 last = j; 1404 return pollv[j].fd; 1405 } 1406 } 1407 fprintf(stderr, "strace: nothing ready\n"); 1408 exit(1); 1409} 1410 1411static int 1412trace() 1413{ 1414#ifdef POLL_HACK 1415 struct tcb *in_syscall; 1416#endif 1417 struct tcb *tcp; 1418 int pfd; 1419 int what; 1420 int ioctl_result = 0, ioctl_errno = 0; 1421 long arg; 1422 1423 for (;;) { 1424 if (interactive) 1425 sigprocmask(SIG_SETMASK, &empty_set, NULL); 1426 1427 if (nprocs == 0) 1428 break; 1429 1430 switch (nprocs) { 1431 case 1: 1432#ifndef HAVE_POLLABLE_PROCFS 1433 if (proc_poll_pipe[0] == -1) { 1434#endif 1435 tcp = pid2tcb(0); 1436 if (!tcp) 1437 continue; 1438 pfd = tcp->pfd; 1439 if (pfd == -1) 1440 continue; 1441 break; 1442#ifndef HAVE_POLLABLE_PROCFS 1443 } 1444 /* fall through ... */ 1445#endif /* !HAVE_POLLABLE_PROCFS */ 1446 default: 1447#ifdef HAVE_POLLABLE_PROCFS 1448#ifdef POLL_HACK 1449 /* On some systems (e.g. UnixWare) we get too much ugly 1450 "unfinished..." stuff when multiple proceses are in 1451 syscalls. Here's a nasty hack */ 1452 1453 if (in_syscall) { 1454 struct pollfd pv; 1455 tcp = in_syscall; 1456 in_syscall = NULL; 1457 pv.fd = tcp->pfd; 1458 pv.events = POLLWANT; 1459 if ((what = poll (&pv, 1, 1)) < 0) { 1460 if (interrupted) 1461 return 0; 1462 continue; 1463 } 1464 else if (what == 1 && pv.revents & POLLWANT) { 1465 goto FOUND; 1466 } 1467 } 1468#endif 1469 1470 if (poll(pollv, nprocs, INFTIM) < 0) { 1471 if (interrupted) 1472 return 0; 1473 continue; 1474 } 1475#else /* !HAVE_POLLABLE_PROCFS */ 1476 if (proc_poll(pollv, nprocs, INFTIM) < 0) { 1477 if (interrupted) 1478 return 0; 1479 continue; 1480 } 1481#endif /* !HAVE_POLLABLE_PROCFS */ 1482 pfd = choose_pfd(); 1483 if (pfd == -1) 1484 continue; 1485 break; 1486 } 1487 1488 /* Look up `pfd' in our table. */ 1489 if ((tcp = pfd2tcb(pfd)) == NULL) { 1490 fprintf(stderr, "unknown pfd: %u\n", pfd); 1491 exit(1); 1492 } 1493 FOUND: 1494 /* Get the status of the process. */ 1495 if (!interrupted) { 1496#ifndef FREEBSD 1497 ioctl_result = IOCTL_WSTOP (tcp); 1498#else /* FREEBSD */ 1499 /* Thanks to some scheduling mystery, the first poller 1500 sometimes waits for the already processed end of fork 1501 event. Doing a non blocking poll here solves the problem. */ 1502 if (proc_poll_pipe[0] != -1) 1503 ioctl_result = IOCTL_STATUS (tcp); 1504 else 1505 ioctl_result = IOCTL_WSTOP (tcp); 1506#endif /* FREEBSD */ 1507 ioctl_errno = errno; 1508#ifndef HAVE_POLLABLE_PROCFS 1509 if (proc_poll_pipe[0] != -1) { 1510 if (ioctl_result < 0) 1511 kill(poller_pid, SIGKILL); 1512 else 1513 kill(poller_pid, SIGUSR1); 1514 } 1515#endif /* !HAVE_POLLABLE_PROCFS */ 1516 } 1517 if (interrupted) 1518 return 0; 1519 1520 if (interactive) 1521 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1522 1523 if (ioctl_result < 0) { 1524 /* Find out what happened if it failed. */ 1525 switch (ioctl_errno) { 1526 case EINTR: 1527 case EBADF: 1528 continue; 1529#ifdef FREEBSD 1530 case ENOTTY: 1531#endif 1532 case ENOENT: 1533 droptcb(tcp); 1534 continue; 1535 default: 1536 perror("PIOCWSTOP"); 1537 exit(1); 1538 } 1539 } 1540 1541#ifdef FREEBSD 1542 if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 1543 /* discard first event for a syscall we never entered */ 1544 IOCTL (tcp->pfd, PIOCRUN, 0); 1545 continue; 1546 } 1547#endif 1548 1549 /* clear the just started flag */ 1550 tcp->flags &= ~TCB_STARTUP; 1551 1552 /* set current output file */ 1553 outf = tcp->outf; 1554 1555 if (cflag) { 1556 struct timeval stime; 1557#ifdef FREEBSD 1558 char buf[1024]; 1559 int len; 1560 1561 if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 1562 buf[len] = '\0'; 1563 sscanf(buf, 1564 "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 1565 &stime.tv_sec, &stime.tv_usec); 1566 } else 1567 stime.tv_sec = stime.tv_usec = 0; 1568#else /* !FREEBSD */ 1569 stime.tv_sec = tcp->status.pr_stime.tv_sec; 1570 stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 1571#endif /* !FREEBSD */ 1572 tv_sub(&tcp->dtime, &stime, &tcp->stime); 1573 tcp->stime = stime; 1574 } 1575 what = tcp->status.PR_WHAT; 1576 switch (tcp->status.PR_WHY) { 1577#ifndef FREEBSD 1578 case PR_REQUESTED: 1579 if (tcp->status.PR_FLAGS & PR_ASLEEP) { 1580 tcp->status.PR_WHY = PR_SYSENTRY; 1581 if (trace_syscall(tcp) < 0) { 1582 fprintf(stderr, "syscall trouble\n"); 1583 exit(1); 1584 } 1585 } 1586 break; 1587#endif /* !FREEBSD */ 1588 case PR_SYSENTRY: 1589#ifdef POLL_HACK 1590 in_syscall = tcp; 1591#endif 1592 case PR_SYSEXIT: 1593 if (trace_syscall(tcp) < 0) { 1594 fprintf(stderr, "syscall trouble\n"); 1595 exit(1); 1596 } 1597 break; 1598 case PR_SIGNALLED: 1599 if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) { 1600 printleader(tcp); 1601 tprintf("--- %s (%s) ---", 1602 signame(what), strsignal(what)); 1603 printtrailer(tcp); 1604#ifdef PR_INFO 1605 if (tcp->status.PR_INFO.si_signo == what) { 1606 printleader(tcp); 1607 tprintf(" siginfo="); 1608 printsiginfo(&tcp->status.PR_INFO, 1); 1609 printtrailer(tcp); 1610 } 1611#endif 1612 } 1613 break; 1614 case PR_FAULTED: 1615 if (!cflag && (qual_flags[what] & QUAL_FAULT)) { 1616 printleader(tcp); 1617 tprintf("=== FAULT %d ===", what); 1618 printtrailer(tcp); 1619 } 1620 break; 1621#ifdef FREEBSD 1622 case 0: /* handle case we polled for nothing */ 1623 continue; 1624#endif 1625 default: 1626 fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY); 1627 exit(1); 1628 break; 1629 } 1630 arg = 0; 1631#ifndef FREEBSD 1632 if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 1633#else 1634 if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) { 1635#endif 1636 perror("PIOCRUN"); 1637 exit(1); 1638 } 1639 } 1640 return 0; 1641} 1642 1643#else /* !USE_PROCFS */ 1644 1645static int 1646trace() 1647{ 1648 int pid; 1649 int wait_errno; 1650 int status; 1651 struct tcb *tcp; 1652#ifdef LINUX 1653 struct rusage ru; 1654#ifdef __WALL 1655 static int wait4_options = __WALL; 1656#endif 1657#endif /* LINUX */ 1658 1659 while (nprocs != 0) { 1660 if (interactive) 1661 sigprocmask(SIG_SETMASK, &empty_set, NULL); 1662#ifdef LINUX 1663#ifdef __WALL 1664 pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL); 1665 if ((wait4_options & __WALL) && errno == EINVAL) { 1666 /* this kernel does not support __WALL */ 1667 wait4_options &= ~__WALL; 1668 errno = 0; 1669 pid = wait4(-1, &status, wait4_options, 1670 cflag ? &ru : NULL); 1671 } 1672 if (!(wait4_options & __WALL) && errno == ECHILD) { 1673 /* most likely a "cloned" process */ 1674 pid = wait4(-1, &status, __WCLONE, 1675 cflag ? &ru : NULL); 1676 if (pid == -1) { 1677 fprintf(stderr, "strace: clone wait4 " 1678 "failed: %s\n", strerror(errno)); 1679 } 1680 } 1681#else 1682 pid = wait4(-1, &status, 0, cflag ? &ru : NULL); 1683#endif /* __WALL */ 1684#endif /* LINUX */ 1685#ifdef SUNOS4 1686 pid = wait(&status); 1687#endif /* SUNOS4 */ 1688 wait_errno = errno; 1689 if (interactive) 1690 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1691 1692 if (interrupted) 1693 return 0; 1694 1695 if (pid == -1) { 1696 switch (wait_errno) { 1697 case EINTR: 1698 continue; 1699 case ECHILD: 1700 /* 1701 * We would like to verify this case 1702 * but sometimes a race in Solbourne's 1703 * version of SunOS sometimes reports 1704 * ECHILD before sending us SIGCHILD. 1705 */ 1706#if 0 1707 if (nprocs == 0) 1708 return 0; 1709 fprintf(stderr, "strace: proc miscount\n"); 1710 exit(1); 1711#endif 1712 return 0; 1713 default: 1714 errno = wait_errno; 1715 perror("strace: wait"); 1716 return -1; 1717 } 1718 } 1719 if (debug) 1720 fprintf(stderr, " [wait(%#x) = %u]\n", status, pid); 1721 1722 /* Look up `pid' in our table. */ 1723 if ((tcp = pid2tcb(pid)) == NULL) { 1724#if 0 /* XXX davidm */ /* WTA: disabled again */ 1725 struct tcb *tcpchild; 1726 1727 if ((tcpchild = alloctcb(pid)) == NULL) { 1728 fprintf(stderr, " [tcb table full]\n"); 1729 kill(pid, SIGKILL); /* XXX */ 1730 return 0; 1731 } 1732 tcpchild->flags |= TCB_ATTACHED; 1733 newoutf(tcpchild); 1734 tcp->nchildren++; 1735 if (!qflag) 1736 fprintf(stderr, "Process %d attached\n", pid); 1737#else 1738 fprintf(stderr, "unknown pid: %u\n", pid); 1739 if (WIFSTOPPED(status)) 1740 ptrace(PTRACE_CONT, pid, (char *) 1, 0); 1741 exit(1); 1742#endif 1743 } 1744 /* set current output file */ 1745 outf = tcp->outf; 1746 if (cflag) { 1747#ifdef LINUX 1748 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 1749 tcp->stime = ru.ru_stime; 1750#endif /* !LINUX */ 1751 } 1752 1753 if (tcp->flags & TCB_SUSPENDED) { 1754 /* 1755 * Apparently, doing any ptrace() call on a stopped 1756 * process, provokes the kernel to report the process 1757 * status again on a subsequent wait(), even if the 1758 * process has not been actually restarted. 1759 * Since we have inspected the arguments of suspended 1760 * processes we end up here testing for this case. 1761 */ 1762 continue; 1763 } 1764 if (WIFSIGNALED(status)) { 1765 if (!cflag 1766 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 1767 printleader(tcp); 1768 tprintf("+++ killed by %s +++", 1769 signame(WTERMSIG(status))); 1770 printtrailer(tcp); 1771 } 1772 droptcb(tcp); 1773 continue; 1774 } 1775 if (WIFEXITED(status)) { 1776 if (debug) 1777 fprintf(stderr, "pid %u exited\n", pid); 1778 if (tcp->flags & TCB_ATTACHED) 1779 fprintf(stderr, 1780 "PANIC: attached pid %u exited\n", 1781 pid); 1782 droptcb(tcp); 1783 continue; 1784 } 1785 if (!WIFSTOPPED(status)) { 1786 fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 1787 droptcb(tcp); 1788 continue; 1789 } 1790 if (debug) 1791 fprintf(stderr, "pid %u stopped, [%s]\n", 1792 pid, signame(WSTOPSIG(status))); 1793 1794 if (tcp->flags & TCB_STARTUP) { 1795 /* 1796 * This flag is there to keep us in sync. 1797 * Next time this process stops it should 1798 * really be entering a system call. 1799 */ 1800 tcp->flags &= ~TCB_STARTUP; 1801 if (tcp->flags & TCB_ATTACHED) { 1802 /* 1803 * Interestingly, the process may stop 1804 * with STOPSIG equal to some other signal 1805 * than SIGSTOP if we happend to attach 1806 * just before the process takes a signal. 1807 */ 1808 if (!WIFSTOPPED(status)) { 1809 fprintf(stderr, 1810 "pid %u not stopped\n", pid); 1811 detach(tcp, WSTOPSIG(status)); 1812 continue; 1813 } 1814 } 1815 else { 1816#ifdef SUNOS4 1817 /* A child of us stopped at exec */ 1818 if (WSTOPSIG(status) == SIGTRAP && followvfork) 1819 fixvfork(tcp); 1820#endif /* SUNOS4 */ 1821 } 1822 if (tcp->flags & TCB_BPTSET) { 1823 if (clearbpt(tcp) < 0) /* Pretty fatal */ { 1824 droptcb(tcp); 1825 cleanup(); 1826 return -1; 1827 } 1828 } 1829 goto tracing; 1830 } 1831 1832 if (WSTOPSIG(status) != SIGTRAP) { 1833 if (WSTOPSIG(status) == SIGSTOP && 1834 (tcp->flags & TCB_SIGTRAPPED)) { 1835 /* 1836 * Trapped attempt to block SIGTRAP 1837 * Hope we are back in control now. 1838 */ 1839 tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 1840 if (ptrace(PTRACE_SYSCALL, 1841 pid, (char *) 1, 0) < 0) { 1842 perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 1843 cleanup(); 1844 return -1; 1845 } 1846 continue; 1847 } 1848 if (!cflag 1849 && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 1850 unsigned long addr = 0, pc = 0; 1851#ifdef PT_GETSIGINFO 1852# define PSR_RI 41 1853 struct siginfo si; 1854 unsigned long psr; 1855 1856 upeek(pid, PT_CR_IPSR, &psr); 1857 upeek(pid, PT_CR_IIP, &pc); 1858 1859 pc += (psr >> PSR_RI) & 0x3; 1860 ptrace(PT_GETSIGINFO, pid, 0, (long) &si); 1861 addr = (unsigned long) si.si_addr; 1862#endif 1863 printleader(tcp); 1864 tprintf("--- %s (%s) @ %lx (%lx) ---", 1865 signame(WSTOPSIG(status)), 1866 strsignal(WSTOPSIG(status)), pc, addr); 1867 printtrailer(tcp); 1868 } 1869 if ((tcp->flags & TCB_ATTACHED) && 1870 !sigishandled(tcp, WSTOPSIG(status))) { 1871 detach(tcp, WSTOPSIG(status)); 1872 continue; 1873 } 1874 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 1875 WSTOPSIG(status)) < 0) { 1876 perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 1877 cleanup(); 1878 return -1; 1879 } 1880 tcp->flags &= ~TCB_SUSPENDED; 1881 continue; 1882 } 1883 if (trace_syscall(tcp) < 0) { 1884 if (tcp->flags & TCB_ATTACHED) 1885 detach(tcp, 0); 1886 else { 1887 ptrace(PTRACE_KILL, 1888 tcp->pid, (char *) 1, SIGTERM); 1889 droptcb(tcp); 1890 } 1891 continue; 1892 } 1893 if (tcp->flags & TCB_EXITING) { 1894 if (tcp->flags & TCB_ATTACHED) 1895 detach(tcp, 0); 1896 else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) { 1897 perror("strace: ptrace(PTRACE_CONT, ...)"); 1898 cleanup(); 1899 return -1; 1900 } 1901 continue; 1902 } 1903 if (tcp->flags & TCB_SUSPENDED) { 1904 if (!qflag) 1905 fprintf(stderr, "Process %u suspended\n", pid); 1906 continue; 1907 } 1908 tracing: 1909 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) { 1910 perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 1911 cleanup(); 1912 return -1; 1913 } 1914 } 1915 return 0; 1916} 1917 1918#endif /* !USE_PROCFS */ 1919 1920static int curcol; 1921 1922#ifdef __STDC__ 1923#include <stdarg.h> 1924#define VA_START(a, b) va_start(a, b) 1925#else 1926#include <varargs.h> 1927#define VA_START(a, b) va_start(a) 1928#endif 1929 1930void 1931#ifdef __STDC__ 1932tprintf(const char *fmt, ...) 1933#else 1934tprintf(fmt, va_alist) 1935char *fmt; 1936va_dcl 1937#endif 1938{ 1939 va_list args; 1940 1941 VA_START(args, fmt); 1942 if (outf) 1943 curcol += vfprintf(outf, fmt, args); 1944 va_end(args); 1945 return; 1946} 1947 1948void 1949printleader(tcp) 1950struct tcb *tcp; 1951{ 1952 if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) { 1953 tcp_last->flags |= TCB_REPRINT; 1954 tprintf(" <unfinished ...>\n"); 1955 } 1956 curcol = 0; 1957 if ((followfork == 1 || pflag_seen > 1) && outfname) 1958 tprintf("%-5d ", tcp->pid); 1959 else if (nprocs > 1 && !outfname) 1960 tprintf("[pid %5u] ", tcp->pid); 1961 if (tflag) { 1962 char str[sizeof("HH:MM:SS")]; 1963 struct timeval tv, dtv; 1964 static struct timeval otv; 1965 1966 gettimeofday(&tv, NULL); 1967 if (rflag) { 1968 if (otv.tv_sec == 0) 1969 otv = tv; 1970 tv_sub(&dtv, &tv, &otv); 1971 tprintf("%6ld.%06ld ", 1972 (long) dtv.tv_sec, (long) dtv.tv_usec); 1973 otv = tv; 1974 } 1975 else if (tflag > 2) { 1976 tprintf("%ld.%06ld ", 1977 (long) tv.tv_sec, (long) tv.tv_usec); 1978 } 1979 else { 1980 time_t local = tv.tv_sec; 1981 strftime(str, sizeof(str), "%T", localtime(&local)); 1982 if (tflag > 1) 1983 tprintf("%s.%06ld ", str, (long) tv.tv_usec); 1984 else 1985 tprintf("%s ", str); 1986 } 1987 } 1988 if (iflag) 1989 printcall(tcp); 1990} 1991 1992void 1993tabto(col) 1994int col; 1995{ 1996 if (curcol < col) 1997 tprintf("%*s", col - curcol, ""); 1998} 1999 2000void 2001printtrailer(tcp) 2002struct tcb *tcp; 2003{ 2004 tprintf("\n"); 2005 tcp_last = NULL; 2006} 2007 2008#ifdef HAVE_MP_PROCFS 2009 2010int mp_ioctl (int fd, int cmd, void *arg, int size) { 2011 2012 struct iovec iov[2]; 2013 int n = 1; 2014 2015 iov[0].iov_base = &cmd; 2016 iov[0].iov_len = sizeof cmd; 2017 if (arg) { 2018 ++n; 2019 iov[1].iov_base = arg; 2020 iov[1].iov_len = size; 2021 } 2022 2023 return writev (fd, iov, n); 2024} 2025 2026#endif 2027