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