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