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 70int debug = 0, followfork = 0, followvfork = 0, interactive = 0; 71int rflag = 0, tflag = 0, dtime = 0, cflag = 0; 72int iflag = 0, xflag = 0, qflag = 0; 73int pflag_seen = 0; 74 75/* Sometimes we want to print only succeeding syscalls. */ 76int not_failing_only = 0; 77 78char *username = NULL; 79uid_t run_uid; 80gid_t run_gid; 81 82int acolumn = DEFAULT_ACOLUMN; 83int max_strlen = DEFAULT_STRLEN; 84char *outfname = NULL; 85FILE *outf; 86struct tcb **tcbtab; 87unsigned int nprocs, tcbtabsize; 88char *progname; 89extern char **environ; 90 91static int trace P((void)); 92static void cleanup P((void)); 93static void interrupt P((int sig)); 94static sigset_t empty_set, blocked_set; 95 96#ifdef HAVE_SIG_ATOMIC_T 97static volatile sig_atomic_t interrupted; 98#else /* !HAVE_SIG_ATOMIC_T */ 99#ifdef __STDC__ 100static volatile int interrupted; 101#else /* !__STDC__ */ 102static int interrupted; 103#endif /* !__STDC__ */ 104#endif /* !HAVE_SIG_ATOMIC_T */ 105 106#ifdef USE_PROCFS 107 108static struct tcb *pfd2tcb P((int pfd)); 109static void reaper P((int sig)); 110static void rebuild_pollv P((void)); 111static struct pollfd *pollv; 112 113#ifndef HAVE_POLLABLE_PROCFS 114 115static void proc_poll_open P((void)); 116static void proc_poller P((int pfd)); 117 118struct proc_pollfd { 119 int fd; 120 int revents; 121 int pid; 122}; 123 124static int poller_pid; 125static 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 136static void 137usage(ofp, exitval) 138FILE *ofp; 139int exitval; 140{ 141 fprintf(ofp, "\ 142usage: 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 176void 177foobar() 178{ 179} 180#endif /* MIPS */ 181#endif /* SVR4 */ 182 183int 184main(argc, argv) 185int argc; 186char *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, "\ 469Process %u attached with %u threads - interrupt to quit\n", 470 tcp->pid, ntid); 471 else 472 fprintf(stderr, "\ 473Process %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 691void 692newoutf(tcp) 693struct 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 716int 717expand_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 743struct tcb * 744alloctcb(pid) 745int 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 774int 775proc_open(tcp, attaching) 776struct tcb *tcp; 777int 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 1083struct tcb * 1084pid2tcb(pid) 1085int 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 1102static struct tcb * 1103pfd2tcb(pfd) 1104int 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 1120void 1121droptcb(tcp) 1122struct 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 1181static int 1182resume(tcp) 1183struct 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 1212static int 1213detach(tcp, sig) 1214struct tcb *tcp; 1215int 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 1383static void 1384reaper(sig) 1385int 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 1403static void 1404cleanup() 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 1432static void 1433interrupt(sig) 1434int sig; 1435{ 1436 interrupted = 1; 1437} 1438 1439#ifndef HAVE_STRERROR 1440 1441#if !HAVE_DECL_SYS_ERRLIST 1442extern int sys_nerr; 1443extern char *sys_errlist[]; 1444#endif /* HAVE_DECL_SYS_ERRLIST */ 1445 1446const char * 1447strerror(errno) 1448int 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 1464extern char *sys_siglist[]; 1465#endif 1466#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 1467extern char *_sys_siglist[]; 1468#endif 1469 1470const char * 1471strsignal(sig) 1472int 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 1491static void 1492rebuild_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 1520static void 1521proc_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 1542static int 1543proc_poll(pollv, nfds, timeout) 1544struct pollfd *pollv; 1545int nfds; 1546int 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 1568static void 1569wakeup_handler(sig) 1570int sig; 1571{ 1572} 1573 1574static void 1575proc_poller(pfd) 1576int 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 1655static int 1656choose_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 1696static int 1697trace() 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*/ 1939static int 1940handle_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 2005static int 2006trace() 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, "\ 2104Process %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 2339static 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 2349void 2350#ifdef __STDC__ 2351tprintf(const char *fmt, ...) 2352#else 2353tprintf(fmt, va_alist) 2354char *fmt; 2355va_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 2373void 2374printleader(tcp) 2375struct 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 2417void 2418tabto(col) 2419int col; 2420{ 2421 if (curcol < col) 2422 tprintf("%*s", col - curcol, ""); 2423} 2424 2425void 2426printtrailer(tcp) 2427struct tcb *tcp; 2428{ 2429 tprintf("\n"); 2430 tcp_last = NULL; 2431} 2432 2433#ifdef HAVE_MP_PROCFS 2434 2435int 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