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