strace.c revision e8172b79e3dd35a136f4dc4d4de9df5bb4565c01
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 <stdarg.h> 37#include <signal.h> 38#include <errno.h> 39#include <sys/param.h> 40#include <fcntl.h> 41#include <sys/resource.h> 42#include <sys/wait.h> 43#include <sys/stat.h> 44#include <pwd.h> 45#include <grp.h> 46#include <string.h> 47#include <dirent.h> 48#include <sys/utsname.h> 49 50# include <asm/unistd.h> 51# if defined __NR_tkill 52# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 53# else 54 /* kill() may choose arbitrarily the target task of the process group 55 while we later wait on a that specific TID. PID process waits become 56 TID task specific waits for a process under ptrace(2). */ 57# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 58# define my_tkill(tid, sig) kill((tid), (sig)) 59# endif 60 61#if defined(IA64) 62# include <asm/ptrace_offsets.h> 63#endif 64 65extern char **environ; 66extern int optind; 67extern char *optarg; 68 69int debug = 0, followfork = 0; 70unsigned int ptrace_setoptions = 0; 71/* Which WSTOPSIG(status) value marks syscall traps? */ 72static unsigned int syscall_trap_sig = SIGTRAP; 73int dtime = 0, xflag = 0, qflag = 0; 74cflag_t cflag = CFLAG_NONE; 75static int iflag = 0, pflag_seen = 0, rflag = 0, tflag = 0; 76 77/* -I n */ 78enum { 79 INTR_NOT_SET = 0, 80 INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 81 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 82 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 83 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 84 NUM_INTR_OPTS 85}; 86static int opt_intr; 87/* We play with signal mask only if this mode is active: */ 88#define interactive (opt_intr == INTR_WHILE_WAIT) 89 90/* 91 * daemonized_tracer supports -D option. 92 * With this option, strace forks twice. 93 * Unlike normal case, with -D *grandparent* process exec's, 94 * becoming a traced process. Child exits (this prevents traced process 95 * from having children it doesn't expect to have), and grandchild 96 * attaches to grandparent similarly to strace -p PID. 97 * This allows for more transparent interaction in cases 98 * when process and its parent are communicating via signals, 99 * wait() etc. Without -D, strace process gets lodged in between, 100 * disrupting parent<->child link. 101 */ 102static bool daemonized_tracer = 0; 103 104#ifdef USE_SEIZE 105static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 106# define use_seize (post_attach_sigstop == 0) 107#else 108# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 109# define use_seize 0 110#endif 111 112/* Sometimes we want to print only succeeding syscalls. */ 113int not_failing_only = 0; 114 115/* Show path associated with fd arguments */ 116int show_fd_path = 0; 117 118/* are we filtering traces based on paths? */ 119int tracing_paths = 0; 120 121static int exit_code = 0; 122static int strace_child = 0; 123static int strace_tracer_pid = 0; 124 125static char *username = NULL; 126static uid_t run_uid; 127static gid_t run_gid; 128 129int max_strlen = DEFAULT_STRLEN; 130static int acolumn = DEFAULT_ACOLUMN; 131static char *acolumn_spaces; 132static char *outfname = NULL; 133static FILE *outf; 134struct tcb *printing_tcp = NULL; 135static int curcol; 136static struct tcb **tcbtab; 137static unsigned int nprocs, tcbtabsize; 138static const char *progname; 139 140static char *os_release; /* from uname() */ 141 142static int detach(struct tcb *tcp); 143static int trace(void); 144static void cleanup(void); 145static void interrupt(int sig); 146static sigset_t empty_set, blocked_set; 147 148#ifdef HAVE_SIG_ATOMIC_T 149static volatile sig_atomic_t interrupted; 150#else 151static volatile int interrupted; 152#endif 153 154static void 155usage(FILE *ofp, int exitval) 156{ 157 fprintf(ofp, "\ 158usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 159 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 160 [-P path] [PROG [ARGS]]\n\ 161 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 162 [PROG [ARGS]]\n\ 163-c -- count time, calls, and errors for each syscall and report summary\n\ 164-C -- like -c but also print regular output while processes are running\n\ 165-D -- run tracer process as a detached grandchild, not as parent\n\ 166-f -- follow forks, -ff -- with output into separate files\n\ 167-F -- attempt to follow vforks\n\ 168-i -- print instruction pointer at time of syscall\n\ 169-I interruptible\n\ 170 1: no signals are blocked\n\ 171 2: fatal signals are blocked while decoding syscall (default)\n\ 172 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 173 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 174 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 175-q -- suppress messages about attaching, detaching, etc.\n\ 176-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 177-T -- print time spent in each syscall\n\ 178-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 179-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 180-y -- print paths associated with file descriptor arguments\n\ 181-h -- print help message\n\ 182-V -- print version\n\ 183-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 184-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 185 options: trace, abbrev, verbose, raw, signal, read, or write\n\ 186-o file -- send trace output to FILE instead of stderr\n\ 187-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 188-p pid -- trace process with process id PID, may be repeated\n\ 189-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 190-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 191-u username -- run command as username handling setuid and/or setgid\n\ 192-E var=val -- put var=val in the environment for command\n\ 193-E var -- remove var from the environment for command\n\ 194-P path -- trace accesses to path\n\ 195" /* this is broken, so don't document it 196-z -- print only succeeding syscalls\n\ 197 */ 198, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 199 exit(exitval); 200} 201 202static void die(void) __attribute__ ((noreturn)); 203static void die(void) 204{ 205 if (strace_tracer_pid == getpid()) { 206 cflag = 0; 207 cleanup(); 208 } 209 exit(1); 210} 211 212static void verror_msg(int err_no, const char *fmt, va_list p) 213{ 214 char *msg; 215 216 fflush(NULL); 217 218 /* We want to print entire message with single fprintf to ensure 219 * message integrity if stderr is shared with other programs. 220 * Thus we use vasprintf + single fprintf. 221 */ 222 msg = NULL; 223 if (vasprintf(&msg, fmt, p) >= 0) { 224 if (err_no) 225 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 226 else 227 fprintf(stderr, "%s: %s\n", progname, msg); 228 free(msg); 229 } else { 230 /* malloc in vasprintf failed, try it without malloc */ 231 fprintf(stderr, "%s: ", progname); 232 vfprintf(stderr, fmt, p); 233 if (err_no) 234 fprintf(stderr, ": %s\n", strerror(err_no)); 235 else 236 putc('\n', stderr); 237 } 238 /* We don't switch stderr to buffered, thus fprintf(stderr) 239 * always flushes its output and this is not necessary: */ 240 /* fflush(stderr); */ 241} 242 243void error_msg(const char *fmt, ...) 244{ 245 va_list p; 246 va_start(p, fmt); 247 verror_msg(0, fmt, p); 248 va_end(p); 249} 250 251void error_msg_and_die(const char *fmt, ...) 252{ 253 va_list p; 254 va_start(p, fmt); 255 verror_msg(0, fmt, p); 256 die(); 257} 258 259void perror_msg(const char *fmt, ...) 260{ 261 va_list p; 262 va_start(p, fmt); 263 verror_msg(errno, fmt, p); 264 va_end(p); 265} 266 267void perror_msg_and_die(const char *fmt, ...) 268{ 269 va_list p; 270 va_start(p, fmt); 271 verror_msg(errno, fmt, p); 272 die(); 273} 274 275void die_out_of_memory(void) 276{ 277 static bool recursed = 0; 278 if (recursed) 279 exit(1); 280 recursed = 1; 281 error_msg_and_die("Out of memory"); 282} 283 284/* Glue for systems without a MMU that cannot provide fork() */ 285#ifdef HAVE_FORK 286# define strace_vforked 0 287#else 288# define strace_vforked 1 289# define fork() vfork() 290#endif 291 292#ifdef USE_SEIZE 293static int 294ptrace_attach_or_seize(int pid) 295{ 296 int r; 297 if (!use_seize) 298 return ptrace(PTRACE_ATTACH, pid, 0, 0); 299 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 300 if (r) 301 return r; 302 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 303 return r; 304} 305#else 306# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 307#endif 308 309static void 310set_cloexec_flag(int fd) 311{ 312 int flags, newflags; 313 314 flags = fcntl(fd, F_GETFD); 315 if (flags < 0) { 316 /* Can happen only if fd is bad. 317 * Should never happen: if it does, we have a bug 318 * in the caller. Therefore we just abort 319 * instead of propagating the error. 320 */ 321 perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 322 } 323 324 newflags = flags | FD_CLOEXEC; 325 if (flags == newflags) 326 return; 327 328 fcntl(fd, F_SETFD, newflags); /* never fails */ 329} 330 331/* 332 * When strace is setuid executable, we have to swap uids 333 * before and after filesystem and process management operations. 334 */ 335static void 336swap_uid(void) 337{ 338 int euid = geteuid(), uid = getuid(); 339 340 if (euid != uid && setreuid(euid, uid) < 0) { 341 perror_msg_and_die("setreuid"); 342 } 343} 344 345#if _LFS64_LARGEFILE 346# define fopen_for_output fopen64 347#else 348# define fopen_for_output fopen 349#endif 350 351static FILE * 352strace_fopen(const char *path) 353{ 354 FILE *fp; 355 356 swap_uid(); 357 fp = fopen_for_output(path, "w"); 358 if (!fp) 359 perror_msg_and_die("Can't fopen '%s'", path); 360 swap_uid(); 361 set_cloexec_flag(fileno(fp)); 362 return fp; 363} 364 365static int popen_pid = 0; 366 367#ifndef _PATH_BSHELL 368# define _PATH_BSHELL "/bin/sh" 369#endif 370 371/* 372 * We cannot use standard popen(3) here because we have to distinguish 373 * popen child process from other processes we trace, and standard popen(3) 374 * does not export its child's pid. 375 */ 376static FILE * 377strace_popen(const char *command) 378{ 379 FILE *fp; 380 int fds[2]; 381 382 swap_uid(); 383 if (pipe(fds) < 0) 384 perror_msg_and_die("pipe"); 385 386 set_cloexec_flag(fds[1]); /* never fails */ 387 388 popen_pid = vfork(); 389 if (popen_pid == -1) 390 perror_msg_and_die("vfork"); 391 392 if (popen_pid == 0) { 393 /* child */ 394 close(fds[1]); 395 if (fds[0] != 0) { 396 if (dup2(fds[0], 0)) 397 perror_msg_and_die("dup2"); 398 close(fds[0]); 399 } 400 execl(_PATH_BSHELL, "sh", "-c", command, NULL); 401 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 402 } 403 404 /* parent */ 405 close(fds[0]); 406 swap_uid(); 407 fp = fdopen(fds[1], "w"); 408 if (!fp) 409 die_out_of_memory(); 410 return fp; 411} 412 413static void 414newoutf(struct tcb *tcp) 415{ 416 if (outfname && followfork > 1) { 417 char name[520 + sizeof(int) * 3]; 418 sprintf(name, "%.512s.%u", outfname, tcp->pid); 419 tcp->outf = strace_fopen(name); 420 } 421} 422 423static void process_opt_p_list(char *opt) 424{ 425 while (*opt) { 426 /* 427 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". 428 * pidof uses space as delim, pgrep uses newline. :( 429 */ 430 int pid; 431 struct tcb *tcp; 432 char *delim = opt + strcspn(opt, ", \n\t"); 433 char c = *delim; 434 435 *delim = '\0'; 436 pid = atoi(opt); /* TODO: stricter parsing of the number? */ 437 if (pid <= 0) { 438 error_msg("Invalid process id: '%s'", opt); 439 *delim = c; 440 return; 441 } 442 if (pid == strace_tracer_pid) { 443 error_msg("I'm sorry, I can't let you do that, Dave."); 444 *delim = c; 445 return; 446 } 447 *delim = c; 448 tcp = alloc_tcb(pid, 0); 449 tcp->flags |= TCB_ATTACHED; 450 /* 451 * pflag_seen says how many PIDs we handled, 452 * not how many -p opts there were. 453 * Used to decide whether to print pid prefix in logs. 454 */ 455 pflag_seen++; 456 if (c == '\0') 457 break; 458 opt = delim + 1; 459 } 460} 461 462static void 463startup_attach(void) 464{ 465 int tcbi; 466 struct tcb *tcp; 467 468 /* 469 * Block user interruptions as we would leave the traced 470 * process stopped (process state T) if we would terminate in 471 * between PTRACE_ATTACH and wait4() on SIGSTOP. 472 * We rely on cleanup() from this point on. 473 */ 474 if (interactive) 475 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 476 477 if (daemonized_tracer) { 478 pid_t pid = fork(); 479 if (pid < 0) { 480 perror_msg_and_die("fork"); 481 } 482 if (pid) { /* parent */ 483 /* 484 * Wait for grandchild to attach to straced process 485 * (grandparent). Grandchild SIGKILLs us after it attached. 486 * Grandparent's wait() is unblocked by our death, 487 * it proceeds to exec the straced program. 488 */ 489 pause(); 490 _exit(0); /* paranoia */ 491 } 492 /* grandchild */ 493 /* We will be the tracer process. Remember our new pid: */ 494 strace_tracer_pid = getpid(); 495 } 496 497 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 498 tcp = tcbtab[tcbi]; 499 500 /* Is this a process we should attach to, but not yet attached? */ 501 if ((tcp->flags & (TCB_ATTACHED | TCB_STARTUP)) != TCB_ATTACHED) 502 continue; /* no */ 503 504 /* Reinitialize the output since it may have changed */ 505 tcp->outf = outf; 506 newoutf(tcp); 507 508 if (followfork && !daemonized_tracer) { 509 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 510 DIR *dir; 511 512 sprintf(procdir, "/proc/%d/task", tcp->pid); 513 dir = opendir(procdir); 514 if (dir != NULL) { 515 unsigned int ntid = 0, nerr = 0; 516 struct dirent *de; 517 518 while ((de = readdir(dir)) != NULL) { 519 struct tcb *cur_tcp; 520 int tid; 521 522 if (de->d_fileno == 0) 523 continue; 524 tid = atoi(de->d_name); 525 if (tid <= 0) 526 continue; 527 ++ntid; 528 if (ptrace_attach_or_seize(tid) < 0) { 529 ++nerr; 530 if (debug) 531 fprintf(stderr, "attach to pid %d failed\n", tid); 532 continue; 533 } 534 if (debug) 535 fprintf(stderr, "attach to pid %d succeeded\n", tid); 536 cur_tcp = tcp; 537 if (tid != tcp->pid) 538 cur_tcp = alloctcb(tid); 539 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 540 } 541 closedir(dir); 542 if (interactive) { 543 sigprocmask(SIG_SETMASK, &empty_set, NULL); 544 if (interrupted) 545 goto ret; 546 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 547 } 548 ntid -= nerr; 549 if (ntid == 0) { 550 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 551 droptcb(tcp); 552 continue; 553 } 554 if (!qflag) { 555 fprintf(stderr, ntid > 1 556? "Process %u attached with %u threads - interrupt to quit\n" 557: "Process %u attached - interrupt to quit\n", 558 tcp->pid, ntid); 559 } 560 if (!(tcp->flags & TCB_STARTUP)) { 561 /* -p PID, we failed to attach to PID itself 562 * but did attach to some of its sibling threads. 563 * Drop PID's tcp. 564 */ 565 droptcb(tcp); 566 } 567 continue; 568 } /* if (opendir worked) */ 569 } /* if (-f) */ 570 if (ptrace_attach_or_seize(tcp->pid) < 0) { 571 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 572 droptcb(tcp); 573 continue; 574 } 575 tcp->flags |= TCB_STARTUP | post_attach_sigstop; 576 if (debug) 577 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 578 579 if (daemonized_tracer) { 580 /* 581 * It is our grandparent we trace, not a -p PID. 582 * Don't want to just detach on exit, so... 583 */ 584 tcp->flags &= ~TCB_ATTACHED; 585 /* 586 * Make parent go away. 587 * Also makes grandparent's wait() unblock. 588 */ 589 kill(getppid(), SIGKILL); 590 } 591 592 if (!qflag) 593 fprintf(stderr, 594 "Process %u attached - interrupt to quit\n", 595 tcp->pid); 596 } /* for each tcbtab[] */ 597 598 ret: 599 if (interactive) 600 sigprocmask(SIG_SETMASK, &empty_set, NULL); 601} 602 603static void 604startup_child(char **argv) 605{ 606 struct stat statbuf; 607 const char *filename; 608 char pathname[MAXPATHLEN]; 609 int pid = 0; 610 struct tcb *tcp; 611 612 filename = argv[0]; 613 if (strchr(filename, '/')) { 614 if (strlen(filename) > sizeof pathname - 1) { 615 errno = ENAMETOOLONG; 616 perror_msg_and_die("exec"); 617 } 618 strcpy(pathname, filename); 619 } 620#ifdef USE_DEBUGGING_EXEC 621 /* 622 * Debuggers customarily check the current directory 623 * first regardless of the path but doing that gives 624 * security geeks a panic attack. 625 */ 626 else if (stat(filename, &statbuf) == 0) 627 strcpy(pathname, filename); 628#endif /* USE_DEBUGGING_EXEC */ 629 else { 630 const char *path; 631 int m, n, len; 632 633 for (path = getenv("PATH"); path && *path; path += m) { 634 const char *colon = strchr(path, ':'); 635 if (colon) { 636 n = colon - path; 637 m = n + 1; 638 } 639 else 640 m = n = strlen(path); 641 if (n == 0) { 642 if (!getcwd(pathname, MAXPATHLEN)) 643 continue; 644 len = strlen(pathname); 645 } 646 else if (n > sizeof pathname - 1) 647 continue; 648 else { 649 strncpy(pathname, path, n); 650 len = n; 651 } 652 if (len && pathname[len - 1] != '/') 653 pathname[len++] = '/'; 654 strcpy(pathname + len, filename); 655 if (stat(pathname, &statbuf) == 0 && 656 /* Accept only regular files 657 with some execute bits set. 658 XXX not perfect, might still fail */ 659 S_ISREG(statbuf.st_mode) && 660 (statbuf.st_mode & 0111)) 661 break; 662 } 663 } 664 if (stat(pathname, &statbuf) < 0) { 665 perror_msg_and_die("Can't stat '%s'", filename); 666 } 667 strace_child = pid = fork(); 668 if (pid < 0) { 669 perror_msg_and_die("fork"); 670 } 671 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 672 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 673 ) { 674 pid = getpid(); 675 if (outf != stderr) 676 close(fileno(outf)); 677 if (!daemonized_tracer && !use_seize) { 678 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 679 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 680 } 681 } 682 683 if (username != NULL) { 684 uid_t run_euid = run_uid; 685 gid_t run_egid = run_gid; 686 687 if (statbuf.st_mode & S_ISUID) 688 run_euid = statbuf.st_uid; 689 if (statbuf.st_mode & S_ISGID) 690 run_egid = statbuf.st_gid; 691 /* 692 * It is important to set groups before we 693 * lose privileges on setuid. 694 */ 695 if (initgroups(username, run_gid) < 0) { 696 perror_msg_and_die("initgroups"); 697 } 698 if (setregid(run_gid, run_egid) < 0) { 699 perror_msg_and_die("setregid"); 700 } 701 if (setreuid(run_uid, run_euid) < 0) { 702 perror_msg_and_die("setreuid"); 703 } 704 } 705 else if (geteuid() != 0) 706 setreuid(run_uid, run_uid); 707 708 if (!daemonized_tracer) { 709 /* 710 * Induce a ptrace stop. Tracer (our parent) 711 * will resume us with PTRACE_SYSCALL and display 712 * the immediately following execve syscall. 713 * Can't do this on NOMMU systems, we are after 714 * vfork: parent is blocked, stopping would deadlock. 715 */ 716 if (!strace_vforked) 717 kill(pid, SIGSTOP); 718 } else { 719 struct sigaction sv_sigchld; 720 sigaction(SIGCHLD, NULL, &sv_sigchld); 721 /* 722 * Make sure it is not SIG_IGN, otherwise wait 723 * will not block. 724 */ 725 signal(SIGCHLD, SIG_DFL); 726 /* 727 * Wait for grandchild to attach to us. 728 * It kills child after that, and wait() unblocks. 729 */ 730 alarm(3); 731 wait(NULL); 732 alarm(0); 733 sigaction(SIGCHLD, &sv_sigchld, NULL); 734 } 735 736 execv(pathname, argv); 737 perror_msg_and_die("exec"); 738 } 739 740 /* We are the tracer */ 741 742 if (!daemonized_tracer) { 743 if (!use_seize) { 744 /* child did PTRACE_TRACEME, nothing to do in parent */ 745 } else { 746 if (!strace_vforked) { 747 /* Wait until child stopped itself */ 748 int status; 749 while (waitpid(pid, &status, WSTOPPED) < 0) { 750 if (errno == EINTR) 751 continue; 752 perror_msg_and_die("waitpid"); 753 } 754 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 755 kill(pid, SIGKILL); 756 perror_msg_and_die("Unexpected wait status %x", status); 757 } 758 } 759 /* Else: vforked case, we have no way to sync. 760 * Just attach to it as soon as possible. 761 * This means that we may miss a few first syscalls... 762 */ 763 764 if (ptrace_attach_or_seize(pid)) { 765 kill(pid, SIGKILL); 766 perror_msg_and_die("Can't attach to %d", pid); 767 } 768 if (!strace_vforked) 769 kill(pid, SIGCONT); 770 } 771 tcp = alloctcb(pid); 772 if (!strace_vforked) 773 tcp->flags |= TCB_STARTUP | post_attach_sigstop; 774 else 775 tcp->flags |= TCB_STARTUP; 776 } 777 else { 778 /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 779 strace_tracer_pid = getpid(); 780 /* The tracee is our parent: */ 781 pid = getppid(); 782 tcp = alloctcb(pid); 783 /* We want subsequent startup_attach() to attach to it: */ 784 tcp->flags |= TCB_ATTACHED; 785 } 786} 787 788static void kill_save_errno(pid_t pid, int sig) 789{ 790 int saved_errno = errno; 791 792 (void) kill(pid, sig); 793 errno = saved_errno; 794} 795 796/* 797 * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 798 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 799 * and then see which options are supported by the kernel. 800 */ 801static void 802test_ptrace_setoptions_followfork(void) 803{ 804 int pid, expected_grandchild = 0, found_grandchild = 0; 805 const unsigned int test_options = PTRACE_O_TRACECLONE | 806 PTRACE_O_TRACEFORK | 807 PTRACE_O_TRACEVFORK; 808 809 pid = fork(); 810 if (pid < 0) 811 perror_msg_and_die("fork"); 812 if (pid == 0) { 813 pid = getpid(); 814 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 815 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 816 __func__); 817 kill_save_errno(pid, SIGSTOP); 818 if (fork() < 0) 819 perror_msg_and_die("fork"); 820 _exit(0); 821 } 822 823 while (1) { 824 int status, tracee_pid; 825 826 errno = 0; 827 tracee_pid = wait(&status); 828 if (tracee_pid <= 0) { 829 if (errno == EINTR) 830 continue; 831 if (errno == ECHILD) 832 break; 833 kill_save_errno(pid, SIGKILL); 834 perror_msg_and_die("%s: unexpected wait result %d", 835 __func__, tracee_pid); 836 } 837 if (WIFEXITED(status)) { 838 if (WEXITSTATUS(status)) { 839 if (tracee_pid != pid) 840 kill_save_errno(pid, SIGKILL); 841 error_msg_and_die("%s: unexpected exit status %u", 842 __func__, WEXITSTATUS(status)); 843 } 844 continue; 845 } 846 if (WIFSIGNALED(status)) { 847 if (tracee_pid != pid) 848 kill_save_errno(pid, SIGKILL); 849 error_msg_and_die("%s: unexpected signal %u", 850 __func__, WTERMSIG(status)); 851 } 852 if (!WIFSTOPPED(status)) { 853 if (tracee_pid != pid) 854 kill_save_errno(tracee_pid, SIGKILL); 855 kill_save_errno(pid, SIGKILL); 856 error_msg_and_die("%s: unexpected wait status %x", 857 __func__, status); 858 } 859 if (tracee_pid != pid) { 860 found_grandchild = tracee_pid; 861 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 862 kill_save_errno(tracee_pid, SIGKILL); 863 kill_save_errno(pid, SIGKILL); 864 perror_msg_and_die("PTRACE_CONT doesn't work"); 865 } 866 continue; 867 } 868 switch (WSTOPSIG(status)) { 869 case SIGSTOP: 870 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 871 && errno != EINVAL && errno != EIO) 872 perror_msg("PTRACE_SETOPTIONS"); 873 break; 874 case SIGTRAP: 875 if (status >> 16 == PTRACE_EVENT_FORK) { 876 long msg = 0; 877 878 if (ptrace(PTRACE_GETEVENTMSG, pid, 879 NULL, (long) &msg) == 0) 880 expected_grandchild = msg; 881 } 882 break; 883 } 884 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 885 kill_save_errno(pid, SIGKILL); 886 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 887 } 888 } 889 if (expected_grandchild && expected_grandchild == found_grandchild) { 890 ptrace_setoptions |= test_options; 891 if (debug) 892 fprintf(stderr, "ptrace_setoptions = %#x\n", 893 ptrace_setoptions); 894 return; 895 } 896 error_msg("Test for PTRACE_O_TRACECLONE failed, " 897 "giving up using this feature."); 898} 899 900/* 901 * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 902 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 903 * and then see whether it will stop with (SIGTRAP | 0x80). 904 * 905 * Use of this option enables correct handling of user-generated SIGTRAPs, 906 * and SIGTRAPs generated by special instructions such as int3 on x86: 907 * _start: .globl _start 908 * int3 909 * movl $42, %ebx 910 * movl $1, %eax 911 * int $0x80 912 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 913 */ 914static void 915test_ptrace_setoptions_for_all(void) 916{ 917 const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 918 PTRACE_O_TRACEEXEC; 919 int pid; 920 int it_worked = 0; 921 922 pid = fork(); 923 if (pid < 0) 924 perror_msg_and_die("fork"); 925 926 if (pid == 0) { 927 pid = getpid(); 928 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 929 /* Note: exits with exitcode 1 */ 930 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 931 __func__); 932 kill(pid, SIGSTOP); 933 _exit(0); /* parent should see entry into this syscall */ 934 } 935 936 while (1) { 937 int status, tracee_pid; 938 939 errno = 0; 940 tracee_pid = wait(&status); 941 if (tracee_pid <= 0) { 942 if (errno == EINTR) 943 continue; 944 kill_save_errno(pid, SIGKILL); 945 perror_msg_and_die("%s: unexpected wait result %d", 946 __func__, tracee_pid); 947 } 948 if (WIFEXITED(status)) { 949 if (WEXITSTATUS(status) == 0) 950 break; 951 error_msg_and_die("%s: unexpected exit status %u", 952 __func__, WEXITSTATUS(status)); 953 } 954 if (WIFSIGNALED(status)) { 955 error_msg_and_die("%s: unexpected signal %u", 956 __func__, WTERMSIG(status)); 957 } 958 if (!WIFSTOPPED(status)) { 959 kill(pid, SIGKILL); 960 error_msg_and_die("%s: unexpected wait status %x", 961 __func__, status); 962 } 963 if (WSTOPSIG(status) == SIGSTOP) { 964 /* 965 * We don't check "options aren't accepted" error. 966 * If it happens, we'll never get (SIGTRAP | 0x80), 967 * and thus will decide to not use the option. 968 * IOW: the outcome of the test will be correct. 969 */ 970 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 971 && errno != EINVAL && errno != EIO) 972 perror_msg("PTRACE_SETOPTIONS"); 973 } 974 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 975 it_worked = 1; 976 } 977 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 978 kill_save_errno(pid, SIGKILL); 979 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 980 } 981 } 982 983 if (it_worked) { 984 syscall_trap_sig = (SIGTRAP | 0x80); 985 ptrace_setoptions |= test_options; 986 if (debug) 987 fprintf(stderr, "ptrace_setoptions = %#x\n", 988 ptrace_setoptions); 989 return; 990 } 991 992 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 993 "giving up using this feature."); 994} 995 996# ifdef USE_SEIZE 997static void 998test_ptrace_seize(void) 999{ 1000 int pid; 1001 1002 pid = fork(); 1003 if (pid < 0) 1004 perror_msg_and_die("fork"); 1005 1006 if (pid == 0) { 1007 pause(); 1008 _exit(0); 1009 } 1010 1011 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 1012 * attaching tracee continues to run unless a trap condition occurs. 1013 * PTRACE_SEIZE doesn't affect signal or group stop state. 1014 */ 1015 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 1016 post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1017 } else if (debug) { 1018 fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 1019 } 1020 1021 kill(pid, SIGKILL); 1022 1023 while (1) { 1024 int status, tracee_pid; 1025 1026 errno = 0; 1027 tracee_pid = waitpid(pid, &status, 0); 1028 if (tracee_pid <= 0) { 1029 if (errno == EINTR) 1030 continue; 1031 perror_msg_and_die("%s: unexpected wait result %d", 1032 __func__, tracee_pid); 1033 } 1034 if (WIFSIGNALED(status)) { 1035 return; 1036 } 1037 error_msg_and_die("%s: unexpected wait status %x", 1038 __func__, status); 1039 } 1040} 1041# else /* !USE_SEIZE */ 1042# define test_ptrace_seize() ((void)0) 1043# endif 1044 1045/* Noinline: don't want main to have struct utsname permanently on stack */ 1046static void __attribute__ ((noinline)) 1047get_os_release(void) 1048{ 1049 struct utsname u; 1050 if (uname(&u) < 0) 1051 perror_msg_and_die("uname"); 1052 os_release = strdup(u.release); 1053 if (!os_release) 1054 die_out_of_memory(); 1055} 1056 1057int 1058main(int argc, char *argv[]) 1059{ 1060 struct tcb *tcp; 1061 int c; 1062 int optF = 0; 1063 struct sigaction sa; 1064 1065 progname = argv[0] ? argv[0] : "strace"; 1066 1067 strace_tracer_pid = getpid(); 1068 1069 get_os_release(); 1070 1071 /* Allocate the initial tcbtab. */ 1072 tcbtabsize = argc; /* Surely enough for all -p args. */ 1073 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 1074 if (!tcbtab) 1075 die_out_of_memory(); 1076 tcp = calloc(tcbtabsize, sizeof(*tcp)); 1077 if (!tcp) 1078 die_out_of_memory(); 1079 for (c = 0; c < tcbtabsize; c++) 1080 tcbtab[c] = tcp++; 1081 1082 outf = stderr; 1083 set_sortby(DEFAULT_SORTBY); 1084 set_personality(DEFAULT_PERSONALITY); 1085 qualify("trace=all"); 1086 qualify("abbrev=all"); 1087 qualify("verbose=all"); 1088 qualify("signal=all"); 1089 while ((c = getopt(argc, argv, 1090 "+cCdfFhiqrtTvVxyz" 1091 "D" 1092 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 1093 switch (c) { 1094 case 'c': 1095 if (cflag == CFLAG_BOTH) { 1096 error_msg_and_die("-c and -C are mutually exclusive options"); 1097 } 1098 cflag = CFLAG_ONLY_STATS; 1099 break; 1100 case 'C': 1101 if (cflag == CFLAG_ONLY_STATS) { 1102 error_msg_and_die("-c and -C are mutually exclusive options"); 1103 } 1104 cflag = CFLAG_BOTH; 1105 break; 1106 case 'd': 1107 debug++; 1108 break; 1109 case 'D': 1110 daemonized_tracer = 1; 1111 break; 1112 case 'F': 1113 optF = 1; 1114 break; 1115 case 'f': 1116 followfork++; 1117 break; 1118 case 'h': 1119 usage(stdout, 0); 1120 break; 1121 case 'i': 1122 iflag++; 1123 break; 1124 case 'q': 1125 qflag++; 1126 break; 1127 case 'r': 1128 rflag++; 1129 tflag++; 1130 break; 1131 case 't': 1132 tflag++; 1133 break; 1134 case 'T': 1135 dtime++; 1136 break; 1137 case 'x': 1138 xflag++; 1139 break; 1140 case 'y': 1141 show_fd_path = 1; 1142 break; 1143 case 'v': 1144 qualify("abbrev=none"); 1145 break; 1146 case 'V': 1147 printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 1148 exit(0); 1149 break; 1150 case 'z': 1151 not_failing_only = 1; 1152 break; 1153 case 'a': 1154 acolumn = atoi(optarg); 1155 if (acolumn < 0) 1156 error_msg_and_die("Bad column width '%s'", optarg); 1157 break; 1158 case 'e': 1159 qualify(optarg); 1160 break; 1161 case 'o': 1162 outfname = strdup(optarg); 1163 break; 1164 case 'O': 1165 set_overhead(atoi(optarg)); 1166 break; 1167 case 'p': 1168 process_opt_p_list(optarg); 1169 break; 1170 case 'P': 1171 tracing_paths = 1; 1172 if (pathtrace_select(optarg)) { 1173 error_msg_and_die("Failed to select path '%s'", optarg); 1174 } 1175 break; 1176 case 's': 1177 max_strlen = atoi(optarg); 1178 if (max_strlen < 0) { 1179 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1180 } 1181 break; 1182 case 'S': 1183 set_sortby(optarg); 1184 break; 1185 case 'u': 1186 username = strdup(optarg); 1187 break; 1188 case 'E': 1189 if (putenv(optarg) < 0) 1190 die_out_of_memory(); 1191 break; 1192 case 'I': 1193 opt_intr = atoi(optarg); 1194 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1195 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1196 } 1197 break; 1198 default: 1199 usage(stderr, 1); 1200 break; 1201 } 1202 } 1203 argv += optind; 1204 /* argc -= optind; - no need, argc is not used below */ 1205 1206 acolumn_spaces = malloc(acolumn + 1); 1207 if (!acolumn_spaces) 1208 die_out_of_memory(); 1209 memset(acolumn_spaces, ' ', acolumn); 1210 acolumn_spaces[acolumn] = '\0'; 1211 1212 /* Must have PROG [ARGS], or -p PID. Not both. */ 1213 if (!argv[0] == !pflag_seen) 1214 usage(stderr, 1); 1215 1216 if (pflag_seen && daemonized_tracer) { 1217 error_msg_and_die("-D and -p are mutually exclusive options"); 1218 } 1219 1220 if (!followfork) 1221 followfork = optF; 1222 1223 if (followfork > 1 && cflag) { 1224 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1225 } 1226 1227 /* See if they want to run as another user. */ 1228 if (username != NULL) { 1229 struct passwd *pent; 1230 1231 if (getuid() != 0 || geteuid() != 0) { 1232 error_msg_and_die("You must be root to use the -u option"); 1233 } 1234 pent = getpwnam(username); 1235 if (pent == NULL) { 1236 error_msg_and_die("Cannot find user '%s'", username); 1237 } 1238 run_uid = pent->pw_uid; 1239 run_gid = pent->pw_gid; 1240 } 1241 else { 1242 run_uid = getuid(); 1243 run_gid = getgid(); 1244 } 1245 1246 if (followfork) 1247 test_ptrace_setoptions_followfork(); 1248 test_ptrace_setoptions_for_all(); 1249 test_ptrace_seize(); 1250 1251 /* Check if they want to redirect the output. */ 1252 if (outfname) { 1253 /* See if they want to pipe the output. */ 1254 if (outfname[0] == '|' || outfname[0] == '!') { 1255 /* 1256 * We can't do the <outfname>.PID funny business 1257 * when using popen, so prohibit it. 1258 */ 1259 if (followfork > 1) 1260 error_msg_and_die("Piping the output and -ff are mutually exclusive"); 1261 outf = strace_popen(outfname + 1); 1262 } 1263 else if (followfork <= 1) 1264 outf = strace_fopen(outfname); 1265 } 1266 1267 if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1268 char *buf = malloc(BUFSIZ); 1269 if (!buf) 1270 die_out_of_memory(); 1271 setvbuf(outf, buf, _IOLBF, BUFSIZ); 1272 } 1273 if (outfname && argv[0]) { 1274 if (!opt_intr) 1275 opt_intr = INTR_NEVER; 1276 qflag = 1; 1277 } 1278 if (!opt_intr) 1279 opt_intr = INTR_WHILE_WAIT; 1280 1281 /* argv[0] -pPID -oFILE Default interactive setting 1282 * yes 0 0 INTR_WHILE_WAIT 1283 * no 1 0 INTR_WHILE_WAIT 1284 * yes 0 1 INTR_NEVER 1285 * no 1 1 INTR_WHILE_WAIT 1286 */ 1287 1288 /* STARTUP_CHILD must be called before the signal handlers get 1289 installed below as they are inherited into the spawned process. 1290 Also we do not need to be protected by them as during interruption 1291 in the STARTUP_CHILD mode we kill the spawned process anyway. */ 1292 if (argv[0]) 1293 startup_child(argv); 1294 1295 sigemptyset(&empty_set); 1296 sigemptyset(&blocked_set); 1297 sa.sa_handler = SIG_IGN; 1298 sigemptyset(&sa.sa_mask); 1299 sa.sa_flags = 0; 1300 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1301 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1302 if (opt_intr != INTR_ANYWHERE) { 1303 if (opt_intr == INTR_BLOCK_TSTP_TOO) 1304 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1305 /* 1306 * In interactive mode (if no -o OUTFILE, or -p PID is used), 1307 * fatal signals are blocked while syscall stop is processed, 1308 * and acted on in between, when waiting for new syscall stops. 1309 * In non-interactive mode, signals are ignored. 1310 */ 1311 if (opt_intr == INTR_WHILE_WAIT) { 1312 sigaddset(&blocked_set, SIGHUP); 1313 sigaddset(&blocked_set, SIGINT); 1314 sigaddset(&blocked_set, SIGQUIT); 1315 sigaddset(&blocked_set, SIGPIPE); 1316 sigaddset(&blocked_set, SIGTERM); 1317 sa.sa_handler = interrupt; 1318 } 1319 /* SIG_IGN, or set handler for these */ 1320 sigaction(SIGHUP, &sa, NULL); 1321 sigaction(SIGINT, &sa, NULL); 1322 sigaction(SIGQUIT, &sa, NULL); 1323 sigaction(SIGPIPE, &sa, NULL); 1324 sigaction(SIGTERM, &sa, NULL); 1325 } 1326 /* Make sure SIGCHLD has the default action so that waitpid 1327 definitely works without losing track of children. The user 1328 should not have given us a bogus state to inherit, but he might 1329 have. Arguably we should detect SIG_IGN here and pass it on 1330 to children, but probably noone really needs that. */ 1331 sa.sa_handler = SIG_DFL; 1332 sigaction(SIGCHLD, &sa, NULL); 1333 1334 if (pflag_seen || daemonized_tracer) 1335 startup_attach(); 1336 1337 if (trace() < 0) 1338 exit(1); 1339 1340 cleanup(); 1341 fflush(NULL); 1342 if (exit_code > 0xff) { 1343 /* Avoid potential core file clobbering. */ 1344 struct rlimit rlim = {0, 0}; 1345 setrlimit(RLIMIT_CORE, &rlim); 1346 1347 /* Child was killed by a signal, mimic that. */ 1348 exit_code &= 0xff; 1349 signal(exit_code, SIG_DFL); 1350 raise(exit_code); 1351 /* Paranoia - what if this signal is not fatal? 1352 Exit with 128 + signo then. */ 1353 exit_code += 128; 1354 } 1355 exit(exit_code); 1356} 1357 1358static void 1359expand_tcbtab(void) 1360{ 1361 /* Allocate some more TCBs and expand the table. 1362 We don't want to relocate the TCBs because our 1363 callers have pointers and it would be a pain. 1364 So tcbtab is a table of pointers. Since we never 1365 free the TCBs, we allocate a single chunk of many. */ 1366 int i = tcbtabsize; 1367 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 1368 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 1369 if (!newtab || !newtcbs) 1370 die_out_of_memory(); 1371 tcbtabsize *= 2; 1372 tcbtab = newtab; 1373 while (i < tcbtabsize) 1374 tcbtab[i++] = newtcbs++; 1375} 1376 1377struct tcb * 1378alloc_tcb(int pid, int command_options_parsed) 1379{ 1380 int i; 1381 struct tcb *tcp; 1382 1383 if (nprocs == tcbtabsize) 1384 expand_tcbtab(); 1385 1386 for (i = 0; i < tcbtabsize; i++) { 1387 tcp = tcbtab[i]; 1388 if ((tcp->flags & TCB_INUSE) == 0) { 1389 memset(tcp, 0, sizeof(*tcp)); 1390 tcp->pid = pid; 1391 tcp->flags = TCB_INUSE; 1392 tcp->outf = outf; /* Initialise to current out file */ 1393#if SUPPORTED_PERSONALITIES > 1 1394 tcp->currpers = current_personality; 1395#endif 1396 nprocs++; 1397 if (debug) 1398 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 1399 if (command_options_parsed) 1400 newoutf(tcp); 1401 return tcp; 1402 } 1403 } 1404 error_msg_and_die("bug in alloc_tcb"); 1405} 1406 1407static struct tcb * 1408pid2tcb(int pid) 1409{ 1410 int i; 1411 1412 if (pid <= 0) 1413 return NULL; 1414 1415 for (i = 0; i < tcbtabsize; i++) { 1416 struct tcb *tcp = tcbtab[i]; 1417 if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 1418 return tcp; 1419 } 1420 1421 return NULL; 1422} 1423 1424void 1425droptcb(struct tcb *tcp) 1426{ 1427 if (tcp->pid == 0) 1428 return; 1429 1430 nprocs--; 1431 if (debug) 1432 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1433 1434 if (outfname && followfork > 1 && tcp->outf) 1435 fclose(tcp->outf); 1436 1437 memset(tcp, 0, sizeof(*tcp)); 1438} 1439 1440/* detach traced process; continue with sig 1441 Never call DETACH twice on the same process as both unattached and 1442 attached-unstopped processes give the same ESRCH. For unattached process we 1443 would SIGSTOP it and wait for its SIGSTOP notification forever. */ 1444 1445static int 1446detach(struct tcb *tcp) 1447{ 1448 int error = 0; 1449 int status, catch_sigstop; 1450 1451 if (tcp->flags & TCB_BPTSET) 1452 clearbpt(tcp); 1453 1454 /* 1455 * Linux wrongly insists the child be stopped 1456 * before detaching. Arghh. We go through hoops 1457 * to make a clean break of things. 1458 */ 1459#if defined(SPARC) 1460#undef PTRACE_DETACH 1461#define PTRACE_DETACH PTRACE_SUNDETACH 1462#endif 1463 /* 1464 * We attached but possibly didn't see the expected SIGSTOP. 1465 * We must catch exactly one as otherwise the detached process 1466 * would be left stopped (process state T). 1467 */ 1468 catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 1469 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 1470 if (error == 0) { 1471 /* On a clear day, you can see forever. */ 1472 } 1473 else if (errno != ESRCH) { 1474 /* Shouldn't happen. */ 1475 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1476 } 1477 else if (my_tkill(tcp->pid, 0) < 0) { 1478 if (errno != ESRCH) 1479 perror("detach: checking sanity"); 1480 } 1481 else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) { 1482 if (errno != ESRCH) 1483 perror("detach: stopping child"); 1484 } 1485 else 1486 catch_sigstop = 1; 1487 if (catch_sigstop) { 1488 for (;;) { 1489#ifdef __WALL 1490 if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 1491 if (errno == ECHILD) /* Already gone. */ 1492 break; 1493 if (errno != EINVAL) { 1494 perror("detach: waiting"); 1495 break; 1496 } 1497#endif /* __WALL */ 1498 /* No __WALL here. */ 1499 if (waitpid(tcp->pid, &status, 0) < 0) { 1500 if (errno != ECHILD) { 1501 perror("detach: waiting"); 1502 break; 1503 } 1504#ifdef __WCLONE 1505 /* If no processes, try clones. */ 1506 if (wait4(tcp->pid, &status, __WCLONE, 1507 NULL) < 0) { 1508 if (errno != ECHILD) 1509 perror("detach: waiting"); 1510 break; 1511 } 1512#endif /* __WCLONE */ 1513 } 1514#ifdef __WALL 1515 } 1516#endif 1517 if (!WIFSTOPPED(status)) { 1518 /* Au revoir, mon ami. */ 1519 break; 1520 } 1521 if (WSTOPSIG(status) == SIGSTOP) { 1522 ptrace_restart(PTRACE_DETACH, tcp, 0); 1523 break; 1524 } 1525 error = ptrace_restart(PTRACE_CONT, tcp, 1526 WSTOPSIG(status) == syscall_trap_sig ? 0 1527 : WSTOPSIG(status)); 1528 if (error < 0) 1529 break; 1530 } 1531 } 1532 1533 if (!qflag) 1534 fprintf(stderr, "Process %u detached\n", tcp->pid); 1535 1536 droptcb(tcp); 1537 1538 return error; 1539} 1540 1541static void 1542cleanup(void) 1543{ 1544 int i; 1545 struct tcb *tcp; 1546 int fatal_sig; 1547 1548 /* 'interrupted' is a volatile object, fetch it only once */ 1549 fatal_sig = interrupted; 1550 if (!fatal_sig) 1551 fatal_sig = SIGTERM; 1552 1553 for (i = 0; i < tcbtabsize; i++) { 1554 tcp = tcbtab[i]; 1555 if (!(tcp->flags & TCB_INUSE)) 1556 continue; 1557 if (debug) 1558 fprintf(stderr, 1559 "cleanup: looking at pid %u\n", tcp->pid); 1560 if (printing_tcp && 1561 (!outfname || followfork < 2 || printing_tcp == tcp)) { 1562 tprints(" <unfinished ...>\n"); 1563 printing_tcp = NULL; 1564 } 1565 if (tcp->flags & TCB_ATTACHED) 1566 detach(tcp); 1567 else { 1568 kill(tcp->pid, SIGCONT); 1569 kill(tcp->pid, fatal_sig); 1570 } 1571 } 1572 if (cflag) 1573 call_summary(outf); 1574} 1575 1576static void 1577interrupt(int sig) 1578{ 1579 interrupted = sig; 1580} 1581 1582#ifndef HAVE_STRERROR 1583 1584#if !HAVE_DECL_SYS_ERRLIST 1585extern int sys_nerr; 1586extern char *sys_errlist[]; 1587#endif /* HAVE_DECL_SYS_ERRLIST */ 1588 1589const char * 1590strerror(int err_no) 1591{ 1592 static char buf[sizeof("Unknown error %d") + sizeof(int)*3]; 1593 1594 if (err_no < 1 || err_no >= sys_nerr) { 1595 sprintf(buf, "Unknown error %d", err_no); 1596 return buf; 1597 } 1598 return sys_errlist[err_no]; 1599} 1600 1601#endif /* HAVE_STERRROR */ 1602 1603#ifndef HAVE_STRSIGNAL 1604 1605#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 1606extern char *sys_siglist[]; 1607#endif 1608#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 1609extern char *_sys_siglist[]; 1610#endif 1611 1612const char * 1613strsignal(int sig) 1614{ 1615 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3]; 1616 1617 if (sig < 1 || sig >= NSIG) { 1618 sprintf(buf, "Unknown signal %d", sig); 1619 return buf; 1620 } 1621#ifdef HAVE__SYS_SIGLIST 1622 return _sys_siglist[sig]; 1623#else 1624 return sys_siglist[sig]; 1625#endif 1626} 1627 1628#endif /* HAVE_STRSIGNAL */ 1629 1630static int 1631trace(void) 1632{ 1633 struct rusage ru; 1634 struct rusage *rup = cflag ? &ru : NULL; 1635# ifdef __WALL 1636 static int wait4_options = __WALL; 1637# endif 1638 1639 while (nprocs != 0) { 1640 int pid; 1641 int wait_errno; 1642 int status, sig; 1643 int stopped; 1644 struct tcb *tcp; 1645 unsigned event; 1646 1647 if (interrupted) 1648 return 0; 1649 if (interactive) 1650 sigprocmask(SIG_SETMASK, &empty_set, NULL); 1651# ifdef __WALL 1652 pid = wait4(-1, &status, wait4_options, rup); 1653 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 1654 /* this kernel does not support __WALL */ 1655 wait4_options &= ~__WALL; 1656 pid = wait4(-1, &status, wait4_options, rup); 1657 } 1658 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 1659 /* most likely a "cloned" process */ 1660 pid = wait4(-1, &status, __WCLONE, rup); 1661 if (pid < 0) { 1662 perror_msg("wait4(__WCLONE) failed"); 1663 } 1664 } 1665# else 1666 pid = wait4(-1, &status, 0, rup); 1667# endif /* __WALL */ 1668 wait_errno = errno; 1669 if (interactive) 1670 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1671 1672 if (pid < 0) { 1673 switch (wait_errno) { 1674 case EINTR: 1675 continue; 1676 case ECHILD: 1677 /* 1678 * We would like to verify this case 1679 * but sometimes a race in Solbourne's 1680 * version of SunOS sometimes reports 1681 * ECHILD before sending us SIGCHILD. 1682 */ 1683 return 0; 1684 default: 1685 errno = wait_errno; 1686 perror_msg("wait"); 1687 return -1; 1688 } 1689 } 1690 if (pid == popen_pid) { 1691 if (WIFEXITED(status) || WIFSIGNALED(status)) 1692 popen_pid = 0; 1693 continue; 1694 } 1695 1696 event = ((unsigned)status >> 16); 1697 if (debug) { 1698 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 1699 if (event != 0) { 1700 static const char *const event_names[] = { 1701 [PTRACE_EVENT_CLONE] = "CLONE", 1702 [PTRACE_EVENT_FORK] = "FORK", 1703 [PTRACE_EVENT_VFORK] = "VFORK", 1704 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 1705 [PTRACE_EVENT_EXEC] = "EXEC", 1706 [PTRACE_EVENT_EXIT] = "EXIT", 1707 }; 1708 const char *e; 1709 if (event < ARRAY_SIZE(event_names)) 1710 e = event_names[event]; 1711 else { 1712 sprintf(buf, "?? (%u)", event); 1713 e = buf; 1714 } 1715 fprintf(stderr, " PTRACE_EVENT_%s", e); 1716 } 1717 strcpy(buf, "???"); 1718 if (WIFSIGNALED(status)) 1719#ifdef WCOREDUMP 1720 sprintf(buf, "WIFSIGNALED,%ssig=%s", 1721 WCOREDUMP(status) ? "core," : "", 1722 signame(WTERMSIG(status))); 1723#else 1724 sprintf(buf, "WIFSIGNALED,sig=%s", 1725 signame(WTERMSIG(status))); 1726#endif 1727 if (WIFEXITED(status)) 1728 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 1729 if (WIFSTOPPED(status)) 1730 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 1731#ifdef WIFCONTINUED 1732 if (WIFCONTINUED(status)) 1733 strcpy(buf, "WIFCONTINUED"); 1734#endif 1735 fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf); 1736 } 1737 1738 /* Look up 'pid' in our table. */ 1739 tcp = pid2tcb(pid); 1740 1741 /* Under Linux, execve changes pid to thread leader's pid, 1742 * and we see this changed pid on EVENT_EXEC and later, 1743 * execve sysexit. Leader "disappears" without exit 1744 * notification. Let user know that, drop leader's tcb, 1745 * and fix up pid in execve thread's tcb. 1746 * Effectively, execve thread's tcb replaces leader's tcb. 1747 * 1748 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 1749 * on exit syscall) in multithreaded programs exactly 1750 * in order to handle this case. 1751 * 1752 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 1753 * On 2.6 and earlier, it can return garbage. 1754 */ 1755 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') { 1756 long old_pid = 0; 1757 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 1758 && old_pid > 0 1759 && old_pid != pid 1760 ) { 1761 struct tcb *execve_thread = pid2tcb(old_pid); 1762 if (tcp) { 1763 outf = tcp->outf; 1764 curcol = tcp->curcol; 1765 if (!cflag) { 1766 if (printing_tcp) 1767 tprints(" <unfinished ...>\n"); 1768 printleader(tcp); 1769 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 1770 printing_tcp = NULL; 1771 fflush(outf); 1772 } 1773 if (execve_thread) { 1774 /* swap output FILEs (needed for -ff) */ 1775 tcp->outf = execve_thread->outf; 1776 execve_thread->outf = outf; 1777 } 1778 droptcb(tcp); 1779 } 1780 tcp = execve_thread; 1781 if (tcp) { 1782 tcp->pid = pid; 1783 tcp->flags |= TCB_REPRINT; 1784 } 1785 } 1786 } 1787 1788 if (tcp == NULL) { 1789 if (followfork) { 1790 /* This is needed to go with the CLONE_PTRACE 1791 changes in process.c/util.c: we might see 1792 the child's initial trap before we see the 1793 parent return from the clone syscall. 1794 Leave the child suspended until the parent 1795 returns from its system call. Only then 1796 will we have the association of parent and 1797 child so that we know how to do clearbpt 1798 in the child. */ 1799 tcp = alloctcb(pid); 1800 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 1801 if (!qflag) 1802 fprintf(stderr, "Process %d attached\n", 1803 pid); 1804 } 1805 else 1806 /* This can happen if a clone call used 1807 CLONE_PTRACE itself. */ 1808 { 1809 if (WIFSTOPPED(status)) 1810 ptrace(PTRACE_CONT, pid, (char *) 1, 0); 1811 error_msg_and_die("Unknown pid: %u", pid); 1812 } 1813 } 1814 /* set current output file */ 1815 outf = tcp->outf; 1816 curcol = tcp->curcol; 1817 if (cflag) { 1818 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 1819 tcp->stime = ru.ru_stime; 1820 } 1821 1822 if (WIFSIGNALED(status)) { 1823 if (pid == strace_child) 1824 exit_code = 0x100 | WTERMSIG(status); 1825 if (cflag != CFLAG_ONLY_STATS 1826 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 1827 printleader(tcp); 1828#ifdef WCOREDUMP 1829 tprintf("+++ killed by %s %s+++\n", 1830 signame(WTERMSIG(status)), 1831 WCOREDUMP(status) ? "(core dumped) " : ""); 1832#else 1833 tprintf("+++ killed by %s +++\n", 1834 signame(WTERMSIG(status))); 1835#endif 1836 printing_tcp = NULL; 1837 } 1838 fflush(tcp->outf); 1839 droptcb(tcp); 1840 continue; 1841 } 1842 if (WIFEXITED(status)) { 1843 if (pid == strace_child) 1844 exit_code = WEXITSTATUS(status); 1845 if (tcp == printing_tcp) { 1846 tprints(" <unfinished ...>\n"); 1847 printing_tcp = NULL; 1848 } 1849 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 1850 printleader(tcp); 1851 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 1852 printing_tcp = NULL; 1853 } 1854 fflush(tcp->outf); 1855 droptcb(tcp); 1856 continue; 1857 } 1858 if (!WIFSTOPPED(status)) { 1859 fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 1860 droptcb(tcp); 1861 continue; 1862 } 1863 1864 /* Is this the very first time we see this tracee stopped? */ 1865 if (tcp->flags & TCB_STARTUP) { 1866 if (debug) 1867 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 1868 tcp->flags &= ~TCB_STARTUP; 1869 if (tcp->flags & TCB_BPTSET) { 1870 /* 1871 * One example is a breakpoint inherited from 1872 * parent through fork(). 1873 */ 1874 if (clearbpt(tcp) < 0) { 1875 /* Pretty fatal */ 1876 droptcb(tcp); 1877 cleanup(); 1878 return -1; 1879 } 1880 } 1881 if (ptrace_setoptions) { 1882 if (debug) 1883 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 1884 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 1885 if (errno != ESRCH) { 1886 /* Should never happen, really */ 1887 perror_msg_and_die("PTRACE_SETOPTIONS"); 1888 } 1889 } 1890 } 1891 } 1892 1893 sig = WSTOPSIG(status); 1894 1895 if (event != 0) { 1896 /* Ptrace event */ 1897#ifdef USE_SEIZE 1898 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 1899 /* 1900 * PTRACE_INTERRUPT-stop or group-stop. 1901 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 1902 */ 1903 if (sig == SIGSTOP 1904 || sig == SIGTSTP 1905 || sig == SIGTTIN 1906 || sig == SIGTTOU 1907 ) { 1908 stopped = 1; 1909 goto show_stopsig; 1910 } 1911 } 1912#endif 1913 goto restart_tracee_with_sig_0; 1914 } 1915 1916 /* Is this post-attach SIGSTOP? 1917 * Interestingly, the process may stop 1918 * with STOPSIG equal to some other signal 1919 * than SIGSTOP if we happend to attach 1920 * just before the process takes a signal. 1921 */ 1922 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 1923 if (debug) 1924 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 1925 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 1926 goto restart_tracee_with_sig_0; 1927 } 1928 1929 if (sig != syscall_trap_sig) { 1930 siginfo_t si; 1931 1932 /* Nonzero (true) if tracee is stopped by signal 1933 * (as opposed to "tracee received signal"). 1934 */ 1935 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 1936#ifdef USE_SEIZE 1937 show_stopsig: 1938#endif 1939 if (cflag != CFLAG_ONLY_STATS 1940 && (qual_flags[sig] & QUAL_SIGNAL)) { 1941#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 1942 long pc = 0; 1943 long psr = 0; 1944 1945 upeek(tcp, PT_CR_IPSR, &psr); 1946 upeek(tcp, PT_CR_IIP, &pc); 1947 1948# define PSR_RI 41 1949 pc += (psr >> PSR_RI) & 0x3; 1950# define PC_FORMAT_STR " @ %lx" 1951# define PC_FORMAT_ARG , pc 1952#else 1953# define PC_FORMAT_STR "" 1954# define PC_FORMAT_ARG /* nothing */ 1955#endif 1956 printleader(tcp); 1957 if (!stopped) { 1958 tprints("--- "); 1959 printsiginfo(&si, verbose(tcp)); 1960 tprintf(" (%s)" PC_FORMAT_STR " ---\n", 1961 strsignal(sig) 1962 PC_FORMAT_ARG); 1963 } else 1964 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n", 1965 strsignal(sig), 1966 signame(sig) 1967 PC_FORMAT_ARG); 1968 printing_tcp = NULL; 1969 fflush(tcp->outf); 1970 } 1971 1972 if (!stopped) 1973 /* It's signal-delivery-stop. Inject the signal */ 1974 goto restart_tracee; 1975 1976 /* It's group-stop */ 1977#ifdef USE_SEIZE 1978 if (use_seize) { 1979 /* 1980 * This ends ptrace-stop, but does *not* end group-stop. 1981 * This makes stopping signals work properly on straced process 1982 * (that is, process really stops. It used to continue to run). 1983 */ 1984 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 1985 cleanup(); 1986 return -1; 1987 } 1988 continue; 1989 } 1990 /* We don't have PTRACE_LISTEN support... */ 1991#endif 1992 goto restart_tracee; 1993 } 1994 1995 /* We handled quick cases, we are permitted to interrupt now. */ 1996 if (interrupted) 1997 return 0; 1998 1999 /* This should be syscall entry or exit. 2000 * (Or it still can be that pesky post-execve SIGTRAP!) 2001 * Handle it. 2002 */ 2003 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2004 /* ptrace() failed in trace_syscall() with ESRCH. 2005 * Likely a result of process disappearing mid-flight. 2006 * Observed case: exit_group() terminating 2007 * all processes in thread group. 2008 */ 2009 if (tcp->flags & TCB_ATTACHED) { 2010 if (printing_tcp) { 2011 /* Do we have dangling line "syscall(param, param"? 2012 * Finish the line then. 2013 */ 2014 printing_tcp->flags |= TCB_REPRINT; 2015 tprints(" <unfinished ...>\n"); 2016 printing_tcp = NULL; 2017 fflush(tcp->outf); 2018 } 2019 /* We assume that ptrace error was caused by process death. 2020 * We used to detach(tcp) here, but since we no longer 2021 * implement "detach before death" policy/hack, 2022 * we can let this process to report its death to us 2023 * normally, via WIFEXITED or WIFSIGNALED wait status. 2024 */ 2025 } else { 2026 /* It's our real child (and we also trace it) */ 2027 /* my_tkill(pid, SIGKILL); - why? */ 2028 /* droptcb(tcp); - why? */ 2029 } 2030 continue; 2031 } 2032 restart_tracee_with_sig_0: 2033 sig = 0; 2034 restart_tracee: 2035 /* Remember current print column before continuing. */ 2036 tcp->curcol = curcol; 2037 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 2038 cleanup(); 2039 return -1; 2040 } 2041 } 2042 return 0; 2043} 2044 2045void 2046tprintf(const char *fmt, ...) 2047{ 2048 va_list args; 2049 2050 va_start(args, fmt); 2051 if (outf) { 2052 int n = vfprintf(outf, fmt, args); 2053 if (n < 0) { 2054 if (outf != stderr) 2055 perror(outfname == NULL 2056 ? "<writing to pipe>" : outfname); 2057 } else 2058 curcol += n; 2059 } 2060 va_end(args); 2061} 2062 2063void 2064tprints(const char *str) 2065{ 2066 if (outf) { 2067 int n = fputs(str, outf); 2068 if (n >= 0) { 2069 curcol += strlen(str); 2070 return; 2071 } 2072 if (outf != stderr) 2073 perror(outfname == NULL 2074 ? "<writing to pipe>" : outfname); 2075 } 2076} 2077 2078void 2079printleader(struct tcb *tcp) 2080{ 2081 if (printing_tcp) { 2082 if (printing_tcp->ptrace_errno) { 2083 if (printing_tcp->flags & TCB_INSYSCALL) { 2084 tprints(" <unavailable>) "); 2085 tabto(); 2086 } 2087 tprints("= ? <unavailable>\n"); 2088 printing_tcp->ptrace_errno = 0; 2089 } else if (!outfname || followfork < 2 || printing_tcp == tcp) { 2090 printing_tcp->flags |= TCB_REPRINT; 2091 tprints(" <unfinished ...>\n"); 2092 } 2093 } 2094 2095 printing_tcp = tcp; 2096 curcol = 0; 2097 if ((followfork == 1 || pflag_seen > 1) && outfname) 2098 tprintf("%-5d ", tcp->pid); 2099 else if (nprocs > 1 && !outfname) 2100 tprintf("[pid %5u] ", tcp->pid); 2101 if (tflag) { 2102 char str[sizeof("HH:MM:SS")]; 2103 struct timeval tv, dtv; 2104 static struct timeval otv; 2105 2106 gettimeofday(&tv, NULL); 2107 if (rflag) { 2108 if (otv.tv_sec == 0) 2109 otv = tv; 2110 tv_sub(&dtv, &tv, &otv); 2111 tprintf("%6ld.%06ld ", 2112 (long) dtv.tv_sec, (long) dtv.tv_usec); 2113 otv = tv; 2114 } 2115 else if (tflag > 2) { 2116 tprintf("%ld.%06ld ", 2117 (long) tv.tv_sec, (long) tv.tv_usec); 2118 } 2119 else { 2120 time_t local = tv.tv_sec; 2121 strftime(str, sizeof(str), "%T", localtime(&local)); 2122 if (tflag > 1) 2123 tprintf("%s.%06ld ", str, (long) tv.tv_usec); 2124 else 2125 tprintf("%s ", str); 2126 } 2127 } 2128 if (iflag) 2129 printcall(tcp); 2130} 2131 2132void 2133tabto(void) 2134{ 2135 if (curcol < acolumn) 2136 tprints(acolumn_spaces + curcol); 2137} 2138