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