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