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