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