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