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