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