==== //depot/vendor/freebsd/src/usr.bin/truss/Makefile#9 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/Makefile#1 (text+ko) ==== identical ==== //depot/vendor/freebsd/src/usr.bin/truss/amd64-fbsd.c#6 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/amd64-fbsd.c#5 (text+ko) ==== content @@ -43,8 +43,7 @@ */ #include -#include -#include +#include #include #include @@ -63,7 +62,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -113,25 +111,16 @@ void amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - char buf[32]; struct reg regs; int syscall_num; int i, reg; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } @@ -163,7 +152,7 @@ || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -181,8 +170,13 @@ } } if (nargs > i) { - lseek(Procfd, regs.r_rsp + sizeof(register_t), SEEK_SET); - if (read(Procfd, &fsc.args[i], (nargs-i) * sizeof(register_t)) == -1) + struct ptrace_io_desc iorequest; + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.r_rsp + sizeof(register_t)); + iorequest.piod_addr = &fsc.args[i]; + iorequest.piod_len = (nargs - i) * sizeof(register_t); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) return; } @@ -223,7 +217,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -279,25 +273,16 @@ long amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - char buf[32]; struct reg regs; long retval; int i; int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } @@ -328,7 +313,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/extern.h#10 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/extern.h#3 (text+ko) ==== content @@ -32,8 +32,9 @@ */ extern int setup_and_wait(char **); -extern int start_tracing(int, int, int, int); +extern int start_tracing(int); extern void restore_proc(int); +extern void waitevent(struct trussinfo *); extern const char *ioctlname(register_t val); extern char *strsig(int sig); #ifdef __alpha__ @@ -63,4 +64,3 @@ extern long sparc64_syscall_exit(struct trussinfo *, int); #endif -extern int Procfd; ==== //depot/vendor/freebsd/src/usr.bin/truss/i386-fbsd.c#17 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/i386-fbsd.c#4 (text+ko) ==== content @@ -43,9 +43,8 @@ */ #include -#include -#include #include +#include #include #include @@ -63,7 +62,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -113,26 +111,18 @@ void i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { - char buf[32]; struct reg regs; int syscall_num; int i; unsigned int parm_offset; struct syscall *sc = NULL; + struct ptrace_io_desc iorequest; + cpid = trussinfo->curthread->tid; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } - clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } @@ -146,13 +136,11 @@ syscall_num = regs.r_eax; switch (syscall_num) { case SYS_syscall: - lseek(Procfd, parm_offset, SEEK_SET); - read(Procfd, &syscall_num, sizeof(int)); + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); parm_offset += sizeof(int); break; case SYS___syscall: - lseek(Procfd, parm_offset, SEEK_SET); - read(Procfd, &syscall_num, sizeof(int)); + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); parm_offset += sizeof(quad_t); break; } @@ -169,15 +157,19 @@ || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) return; fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - lseek(Procfd, parm_offset, SEEK_SET); - if (read(Procfd, fsc.args, nargs * sizeof(unsigned long)) == -1) + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)parm_offset; + iorequest.piod_addr = fsc.args; + iorequest.piod_len = nargs * sizeof(unsigned long); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) return; if (fsc.name) @@ -218,7 +210,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -274,28 +266,20 @@ long i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - char buf[32]; struct reg regs; long retval; int i; int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } + retval = regs.r_eax; errorp = !!(regs.r_eflags & PSL_C); @@ -323,7 +307,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/i386-linux.c#16 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/i386-linux.c#4 (text+ko) ==== content @@ -41,8 +41,7 @@ */ #include -#include -#include +#include #include #include @@ -60,7 +59,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "linux_syscalls.h" @@ -108,28 +106,20 @@ void i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { - char buf[32]; struct reg regs; int syscall_num; int i; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; - } + } syscall_num = regs.r_eax; fsc.number = syscall_num; @@ -143,7 +133,7 @@ && ((!strcmp(fsc.name, "linux_fork") || !strcmp(fsc.name, "linux_vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -200,7 +190,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -264,28 +254,19 @@ long i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - char buf[32]; struct reg regs; long retval; int i; int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; + cpid = trussinfo->curthread->tid; + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) + { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); } - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { - fprintf(trussinfo->outfile, "\n"); - return (-1); - } retval = regs.r_eax; errorp = !!(regs.r_eflags & PSL_C); @@ -313,7 +294,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/i386.conf#1 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/i386.conf#1 (text+ko) ==== identical ==== //depot/vendor/freebsd/src/usr.bin/truss/i386linux.conf#1 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/i386linux.conf#1 (text+ko) ==== identical ==== //depot/vendor/freebsd/src/usr.bin/truss/ia64-fbsd.c#9 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/ia64-fbsd.c#3 (text+ko) ==== content @@ -43,8 +43,7 @@ */ #include -#include -#include +#include #include #include @@ -62,7 +61,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -112,26 +110,16 @@ void ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - char buf[32]; struct reg regs; int syscall_num; int i; unsigned long *parm_offset; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->id; clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } @@ -158,7 +146,7 @@ || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -204,7 +192,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -260,25 +248,15 @@ long ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - char buf[32]; struct reg regs; long retval; int i; int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } @@ -309,7 +287,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/main.c#24 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/main.c#6 (text+ko) ==== content @@ -39,11 +39,10 @@ */ #include -#include -#include #include #include #include +#include #include #include @@ -59,13 +58,8 @@ #include "truss.h" #include "extern.h" -/* - * It's difficult to parameterize this because it must be - * accessible in a signal handler. - */ +#define MAXARGS 5 -int Procfd; - static void usage(void) { @@ -119,18 +113,19 @@ set_etype(struct trussinfo *trussinfo) { struct ex_types *funcs; - char etype[24]; char progt[32]; - int fd; + + size_t len = sizeof(progt); + int mib[4]; + int error; - sprintf(etype, "/proc/%d/etype", trussinfo->pid); - if ((fd = open(etype, O_RDONLY)) == -1) { - strcpy(progt, "FreeBSD a.out"); - } else { - int len = read(fd, progt, sizeof(progt)); - progt[len-1] = '\0'; - close(fd); - } + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_SV_NAME; + mib[3] = trussinfo->pid; + error = sysctl(mib, 4, progt, &len, NULL, 0); + if (error != 0) + err(2, "can not get etype"); for (funcs = ex_types; funcs->type; funcs++) if (!strcmp(funcs->type, progt)) @@ -167,14 +162,12 @@ int c; int i; char **command; - struct procfs_status pfs; struct ex_types *funcs; - int in_exec, sigexit, initial_open; + int sigexit, initial_open; char *fname; struct trussinfo *trussinfo; char *signame; - in_exec = 0; sigexit = 0; fname = NULL; initial_open = 1; @@ -184,9 +177,12 @@ if (trussinfo == NULL) errx(1, "malloc() failed"); bzero(trussinfo, sizeof(struct trussinfo)); + trussinfo->outfile = stderr; trussinfo->strsize = 32; - + trussinfo->pr_why = S_NONE; + trussinfo->curthread = NULL; + SLIST_INIT(&trussinfo->threadlist); while ((c = getopt(ac, av, "p:o:faedDs:S")) != -1) { switch (c) { case 'p': /* specified pid */ @@ -245,6 +241,7 @@ signal(SIGTERM, SIG_IGN); signal(SIGQUIT, SIG_IGN); } else { + start_tracing(trussinfo->pid); signal(SIGINT, restore_proc); signal(SIGTERM, restore_proc); signal(SIGQUIT, restore_proc); @@ -257,18 +254,9 @@ */ START_TRACE: - Procfd = start_tracing( - trussinfo->pid, initial_open, - S_EXEC | S_SCE | S_SCX | S_CORE | S_EXIT | - ((trussinfo->flags & NOSIGS) ? 0 : S_SIG), - ((trussinfo->flags & FOLLOWFORKS) ? PF_FORK : 0)); + funcs = set_etype(trussinfo); + initial_open = 0; - if (Procfd == -1) - return (0); - - pfs.why = 0; - - funcs = set_etype(trussinfo); /* * At this point, it's a simple loop, waiting for the process to * stop, finding out why, printing out why, and then continuing it. @@ -278,118 +266,92 @@ clock_gettime(CLOCK_REALTIME, &trussinfo->start_time); do { - int val = 0; struct timespec timediff; + waitevent(trussinfo); - if (ioctl(Procfd, PIOCWAIT, &pfs) == -1) - warn("PIOCWAIT top of loop"); - else { - switch(i = pfs.why) { - case S_SCE: - funcs->enter_syscall(trussinfo, pfs.val); - clock_gettime(CLOCK_REALTIME, - &trussinfo->before); - break; - case S_SCX: - clock_gettime(CLOCK_REALTIME, - &trussinfo->after); - /* - * This is so we don't get two messages for - * an exec -- one for the S_EXEC, and one for - * the syscall exit. It also, conveniently, - * ensures that the first message printed out - * isn't the return-from-syscall used to - * create the process. - */ - if (in_exec) { - in_exec = 0; - break; - } + switch(i = trussinfo->pr_why) { + case S_SCE: + funcs->enter_syscall(trussinfo, MAXARGS); + clock_gettime(CLOCK_REALTIME, + &trussinfo->before); + break; + case S_SCX: + clock_gettime(CLOCK_REALTIME, + &trussinfo->after); - if (trussinfo->in_fork && - (trussinfo->flags & FOLLOWFORKS)) { - int childpid; + if (trussinfo->curthread->in_fork && + (trussinfo->flags & FOLLOWFORKS)) { + int childpid; - trussinfo->in_fork = 0; - childpid = - funcs->exit_syscall(trussinfo, - pfs.val); + trussinfo->curthread->in_fork = 0; + childpid = + funcs->exit_syscall(trussinfo, + trussinfo->pr_data); - /* - * Fork a new copy of ourself to trace - * the child of the original traced - * process. - */ - if (fork() == 0) { - trussinfo->pid = childpid; - goto START_TRACE; - } - break; + /* + * Fork a new copy of ourself to trace + * the child of the original traced + * process. + */ + if (fork() == 0) { + trussinfo->pid = childpid; + start_tracing(trussinfo->pid); + goto START_TRACE; } - funcs->exit_syscall(trussinfo, pfs.val); break; - case S_SIG: - if (trussinfo->flags & FOLLOWFORKS) - fprintf(trussinfo->outfile, "%5d: ", - trussinfo->pid); - if (trussinfo->flags & ABSOLUTETIMESTAMPS) { - timespecsubt(&trussinfo->after, - &trussinfo->start_time, &timediff); - fprintf(trussinfo->outfile, "%ld.%09ld ", - (long)timediff.tv_sec, - timediff.tv_nsec); - } - if (trussinfo->flags & RELATIVETIMESTAMPS) { - timespecsubt(&trussinfo->after, - &trussinfo->before, &timediff); - fprintf(trussinfo->outfile, "%ld.%09ld ", - (long)timediff.tv_sec, - timediff.tv_nsec); - } - signame = strsig(pfs.val); - fprintf(trussinfo->outfile, - "SIGNAL %lu (%s)\n", pfs.val, - signame == NULL ? "?" : signame); - free(signame); - sigexit = pfs.val; + } + funcs->exit_syscall(trussinfo, MAXARGS); + break; + case S_SIG: + if (trussinfo->flags & NOSIGS) break; - case S_EXIT: - if (trussinfo->flags & FOLLOWFORKS) - fprintf(trussinfo->outfile, "%5d: ", - trussinfo->pid); - if (trussinfo->flags & ABSOLUTETIMESTAMPS) { - timespecsubt(&trussinfo->after, - &trussinfo->start_time, &timediff); - fprintf(trussinfo->outfile, "%ld.%09ld ", - (long)timediff.tv_sec, - timediff.tv_nsec); - } - if (trussinfo->flags & RELATIVETIMESTAMPS) { - timespecsubt(&trussinfo->after, - &trussinfo->before, &timediff); - fprintf(trussinfo->outfile, "%ld.%09ld ", - (long)timediff.tv_sec, timediff.tv_nsec); - } - fprintf(trussinfo->outfile, - "process exit, rval = %lu\n", pfs.val); - break; - case S_EXEC: - funcs = set_etype(trussinfo); - in_exec = 1; - break; - default: - fprintf(trussinfo->outfile, - "Process stopped because of: %d\n", i); - break; + if (trussinfo->flags & FOLLOWFORKS) + fprintf(trussinfo->outfile, "%5d: ", + trussinfo->pid); + if (trussinfo->flags & ABSOLUTETIMESTAMPS) { + timespecsubt(&trussinfo->after, + &trussinfo->start_time, &timediff); + fprintf(trussinfo->outfile, "%ld.%09ld ", + (long)timediff.tv_sec, + timediff.tv_nsec); + } + if (trussinfo->flags & RELATIVETIMESTAMPS) { + timespecsubt(&trussinfo->after, + &trussinfo->before, &timediff); + fprintf(trussinfo->outfile, "%ld.%09ld ", + (long)timediff.tv_sec, + timediff.tv_nsec); + } + signame = strsig(trussinfo->pr_data); + fprintf(trussinfo->outfile, + "SIGNAL %u (%s)\n", trussinfo->pr_data, + signame == NULL ? "?" : signame); + free(signame); + break; + case S_EXIT: + if (trussinfo->flags & FOLLOWFORKS) + fprintf(trussinfo->outfile, "%5d: ", + trussinfo->pid); + if (trussinfo->flags & ABSOLUTETIMESTAMPS) { + timespecsubt(&trussinfo->after, + &trussinfo->start_time, &timediff); + fprintf(trussinfo->outfile, "%ld.%09ld ", + (long)timediff.tv_sec, + timediff.tv_nsec); + } + if (trussinfo->flags & RELATIVETIMESTAMPS) { + timespecsubt(&trussinfo->after, + &trussinfo->before, &timediff); + fprintf(trussinfo->outfile, "%ld.%09ld ", + (long)timediff.tv_sec, timediff.tv_nsec); } + fprintf(trussinfo->outfile, + "process exit, rval = %u\n", trussinfo->pr_data); + break; + default: + break; } - if (ioctl(Procfd, PIOCCONT, val) == -1) { - if (kill(trussinfo->pid, 0) == -1 && errno == ESRCH) - break; - else - warn("PIOCCONT"); - } - } while (pfs.why != S_EXIT); + } while (trussinfo->pr_why != S_EXIT); fflush(trussinfo->outfile); if (sigexit) { struct rlimit rlp; @@ -400,5 +362,6 @@ (void) signal(sigexit, SIG_DFL); (void) kill(getpid(), sigexit); } + return (0); } ==== //depot/vendor/freebsd/src/usr.bin/truss/powerpc-fbsd.c#1 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/powerpc-fbsd.c#4 (text+ko) ==== content @@ -41,8 +41,7 @@ */ #include -#include -#include +#include #include #include @@ -62,7 +61,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -120,19 +118,10 @@ unsigned int regargs; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } @@ -167,7 +156,7 @@ || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -176,9 +165,16 @@ fsc.args = malloc((1+nargs) * sizeof(unsigned long)); if (nargs > regargs) { + struct ptrace_io_desc iorequest; memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0])); - lseek(Procfd, regs.fixreg[1] + 8, SEEK_SET); - read(Procfd, &fsc.args[regargs], (nargs - regargs) * sizeof(fsc.args[0])); + + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.fixreg[1] + 8); + iorequest.piod_addr = &fsc.args[regargs]; + iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; } else { memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0])); } @@ -220,7 +216,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -275,25 +271,15 @@ long powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - char buf[32]; struct reg regs; long retval; int i; int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "\n"); return (-1); } @@ -332,7 +318,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/setup.c#11 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/setup.c#7 (text+ko) ==== content @@ -38,11 +38,12 @@ */ #include -#include -#include +#include +#include #include #include +#include #include #include #include @@ -51,10 +52,12 @@ #include #include +#include + #include "truss.h" #include "extern.h" -static int evflags = 0; +static int child_pid; /* * setup_and_wait() is called to start a process. All it really does @@ -66,75 +69,28 @@ int setup_and_wait(char *command[]) { - struct procfs_status pfs; - char buf[32]; - int fd; int pid; - int flags; - int loop; + int waitval; - pid = fork(); + pid = vfork(); if (pid == -1) { err(1, "fork failed"); } if (pid == 0) { /* Child */ - int mask = S_EXEC | S_EXIT; - fd = open("/proc/curproc/mem", O_WRONLY); - if (fd == -1) - err(2, "cannot open /proc/curproc/mem"); - fcntl(fd, F_SETFD, 1); - if (ioctl(fd, PIOCBIS, mask) == -1) - err(3, "PIOCBIS"); - flags = PF_LINGER; - /* - * The PF_LINGER flag tells procfs not to wake up the - * process on last close; normally, this is the behaviour - * we want. - */ - if (ioctl(fd, PIOCSFL, flags) == -1) - warn("cannot set PF_LINGER"); + ptrace(PT_TRACE_ME, 0, 0, 0); + setpgid (0, 0); execvp(command[0], command); - mask = ~0; - ioctl(fd, PIOCBIC, ~0); - err(4, "execvp %s", command[0]); + err(1, "execvp %s", command[0]); } + /* Only in the parent here */ - - if (waitpid(pid, NULL, WNOHANG) != 0) { - /* - * Process exited before it got to us -- meaning the exec failed - * miserably -- so we just quietly exit. - */ - exit(1); + if (waitpid(pid, &waitval, 0) < -1) { + err(1, "unexpect stop in waitpid"); + return 0; } - sprintf(buf, "/proc/%d/mem", pid); - - /* Try 6 times to trace our child, waiting 1/2 second each time */ - for (loop=6 ;; loop--) { - if (loop != 6) - usleep(500000); - if ((fd = open(buf, O_RDWR)) == -1) { - if (loop > 0) - continue; - else - err(5, "cannot open1 %s", buf); - } - if (ioctl(fd, PIOCWAIT, &pfs) == -1) { - if (loop >= 0) - continue; - else - err(6, "PIOCWAIT"); - } - if (pfs.why == S_EXIT) { - warnx("process exited before exec'ing"); - ioctl(fd, PIOCCONT, 0); - wait(0); - exit(7); - } else - break; - } - close(fd); + child_pid = pid; + return (pid); } @@ -145,45 +101,24 @@ */ int -start_tracing(int pid, int failisfatal, int eventflags, int flags) +start_tracing(int pid) { - int fd; - char buf[32]; - struct procfs_status tmp; + int waitval; + int ret; + int retry = 10; - sprintf(buf, "/proc/%d/mem", pid); - /* usleep(500000); */ + do { + ret = ptrace(PT_ATTACH, pid, NULL, 0); + usleep(200); + } while(ret && retry-- > 0); + if (ret) + err(1, "can not attach to target process"); - fd = open(buf, O_RDWR); - if (fd == -1) { - /* - * The process may have run away before we could start -- this - * happens with SUGID programs. So we need to see if it still - * exists before we complain bitterly. - */ - if (!failisfatal && kill(pid, 0) == -1) - return (-1); - err(8, "cannot open2 %s", buf); - } + child_pid = pid; + if (waitpid(pid, &waitval, 0) < -1) + err(1, "Unexpect stop in waitpid"); - if (ioctl(fd, PIOCSTATUS, &tmp) == -1) { - err(10, "cannot get procfs status struct"); - } - evflags = tmp.events; - - if (ioctl(fd, PIOCBIS, eventflags) == -1) - err(9, "cannot set procfs event bit mask"); - - /* - * This clears the PF_LINGER set above in setup_and_wait(); - * if truss happens to die before this, then the process - * needs to be woken up via procctl. - */ - - if (ioctl(fd, PIOCSFL, flags) == -1) - warn("cannot clear PF_LINGER"); - - return (fd); + return (0); } /* @@ -193,10 +128,74 @@ * process. */ void -restore_proc(int signo __unused) { +restore_proc(int signo __unused) +{ + int waitval; + + kill(child_pid, SIGSTOP); + if (waitpid(child_pid, &waitval, 0) < -1) + err(1, "Unexpected stop in waitpid"); - ioctl(Procfd, PIOCBIC, ~0); - if (evflags) - ioctl(Procfd, PIOCBIS, evflags); + if (ptrace(PT_DETACH, child_pid, (caddr_t)1, 0) < 0) + err(1, "Can not detach the process"); + + kill(child_pid, SIGCONT); exit(0); } + +void find_thread(struct trussinfo *info, lwpid_t lwpid) +{ + info->curthread = NULL; + struct threadinfo *np; + SLIST_FOREACH(np, &info->threadlist, entries) { + if (np->tid == lwpid) { + info->curthread = np; + return; + } + } + + np = (struct threadinfo *)malloc(sizeof(struct threadinfo)); + if (np == NULL) + errx(1, "malloc() failed"); + np->tid = lwpid; + np->in_fork = 0; + np->in_syscall = 0; + SLIST_INSERT_HEAD(&info->threadlist, np, entries); + info->curthread = np; +} + +void waitevent(struct trussinfo *info) +{ + int waitval; + + ptrace(PT_SYSCALL, info->pid, (caddr_t)1, 0); + + if (waitpid(info->pid, &waitval, 0) < -1) { + err(1, "Unexpected stop in waitpid"); + } + + if (WIFCONTINUED(waitval)) { + info->pr_why = S_NONE; + return; + } + if (WIFEXITED(waitval)) { + info->pr_why = S_EXIT; + info->pr_data = WEXITSTATUS(waitval); + return; + } + if (WIFSTOPPED(waitval) || (WIFSIGNALED(waitval))) { + struct ptrace_lwpinfo lwpinfo; + ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo)); + find_thread(info, lwpinfo.pl_lwpid); + switch(WSTOPSIG(waitval)) { + case SIGTRAP: + info->pr_why = info->curthread->in_syscall?S_SCX:S_SCE; + info->curthread->in_syscall = 1 - info->curthread->in_syscall; + break; + default: + info->pr_why = S_SIG; + info->pr_data = WSTOPSIG(waitval); + break; + } + } +} ==== //depot/vendor/freebsd/src/usr.bin/truss/sparc64-fbsd.c#9 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/sparc64-fbsd.c#3 (text+ko) ==== content @@ -45,8 +45,7 @@ */ #include -#include -#include +#include #include #include @@ -68,7 +67,6 @@ #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -118,26 +116,18 @@ void sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - char buf[32]; struct reg regs; int syscall_num; int i; struct syscall *sc; int indir = 0; /* indirect system call */ + struct ptrace_io_desc iorequest; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDWR); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return; - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; clear_fsc(); - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } @@ -165,7 +155,7 @@ || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -186,9 +176,14 @@ * on the stack, as is normal for other processors. * The fall-through for all of these is deliberate!!! */ - lseek(Procfd, regs.r_out[6] + SPOFF + - offsetof(struct frame, fr_pad[6]), SEEK_SET); - read(fd, &fsc.args[6], (nargs - 6) * sizeof(fsc.args[0])); + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.r_out[6] + SPOFF + + offsetof(struct frame, fr_pad[6]); + iorequest.piod_addr = &fsc.args[6]; + iorequest.piod_len = (nargs - 6) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) return; + case 6: fsc.args[5] = regs.r_out[5]; case 5: fsc.args[4] = regs.r_out[4]; case 4: fsc.args[3] = regs.r_out[3]; @@ -240,7 +235,7 @@ i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo); + fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG @@ -302,18 +297,9 @@ int errorp; struct syscall *sc; - if (fd == -1 || trussinfo->pid != cpid) { - sprintf(buf, "/proc/%d/regs", trussinfo->pid); - fd = open(buf, O_RDONLY); - if (fd == -1) { - fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n"); - return (-1); - } - cpid = trussinfo->pid; - } + cpid = trussinfo->curthread->tid; - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "\n"); return (-1); } @@ -344,7 +330,7 @@ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else - temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo); + temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } ==== //depot/vendor/freebsd/src/usr.bin/truss/syscall.h#12 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/syscall.h#2 (text+ko) ==== content @@ -61,7 +61,7 @@ struct syscall *get_syscall(const char*); char *get_string(int, void*, int); -char *print_arg(int, struct syscall_args *, unsigned long*, long, struct trussinfo *); +char *print_arg(struct syscall_args *, unsigned long*, long, struct trussinfo *); void print_syscall(struct trussinfo *, const char *, int, char **); void print_syscall_ret(struct trussinfo *, const char *, int, char **, int, long); ==== //depot/vendor/freebsd/src/usr.bin/truss/syscalls.c#38 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/syscalls.c#2 (text+ko) ==== content @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -408,9 +409,13 @@ */ static int -get_struct(int procfd, void *offset, void *buf, int len) { - - if (pread(procfd, buf, len, (uintptr_t)offset) != len) +get_struct(int pid, void *offset, void *buf, int len) { + struct ptrace_io_desc iorequest; + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = offset; + iorequest.piod_addr = buf; + iorequest.piod_len = len; + if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) != len) return -1; return 0; } @@ -423,37 +428,21 @@ */ char * -get_string(int procfd, void *offset, int max) { +get_string(int pid, void *offset, int max) { char *buf; - int size, len, c, fd; - FILE *p; + struct ptrace_io_desc iorequest; + if (max > 1024 || max <= 0) + max = 1024; + + buf = malloc(max); + if (buf == NULL) return NULL; + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = offset; + iorequest.piod_addr = buf; + iorequest.piod_len = max; + ptrace(PT_IO, pid, (caddr_t)&iorequest, 0); + buf[max - 1] = '\0'; - if ((fd = dup(procfd)) == -1) - err(1, "dup"); - if ((p = fdopen(fd, "r")) == NULL) - err(1, "fdopen"); - buf = malloc( size = (max ? max + 1 : 64 ) ); - len = 0; - buf[0] = 0; - if (fseeko(p, (uintptr_t)offset, SEEK_SET) == 0) { - while ((c = fgetc(p)) != EOF) { - buf[len++] = c; - if (c == 0 || len == max) - break; - if (len == size) { - char *tmp; - tmp = realloc(buf, size+64); - if (tmp == NULL) { - buf[len] = 0; - break; - } - size += 64; - buf = tmp; - } - } - buf[len] = 0; - } - fclose(p); return (buf); } @@ -469,9 +458,9 @@ */ char * -print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo) { +print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo) { char *tmp = NULL; - + int pid = trussinfo->pid; switch (sc->type & ARG_MASK) { case Hex: asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -486,7 +475,7 @@ { /* NULL-terminated string. */ char *tmp2; - tmp2 = get_string(fd, (void*)args[sc->offset], 0); + tmp2 = get_string(pid, (void*)args[sc->offset], 0); asprintf(&tmp, "\"%s\"", tmp2); free(tmp2); } @@ -514,7 +503,7 @@ len = max_string; truncated = 1; } - if (len && get_struct(fd, (void*)args[sc->offset], &tmp2, len) != -1) { + if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) != -1) { tmp3 = malloc(len * 4 + 1); while (len) { if (strvisx(tmp3, tmp2, len, VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) @@ -535,7 +524,7 @@ char *string; char *strarray[100]; /* XXX This is ugly. */ - if (get_struct(fd, (void *)args[sc->offset], (void *)&strarray, + if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray, sizeof(strarray)) == -1) { err(1, "get_struct %p", (void *)args[sc->offset]); } @@ -544,7 +533,7 @@ /* Find out how large of a buffer we'll need. */ while (strarray[num] != NULL) { - string = get_string(fd, (void*)strarray[num], 0); + string = get_string(pid, (void*)strarray[num], 0); size += strlen(string); free(string); num++; @@ -555,7 +544,7 @@ tmp2 += sprintf(tmp2, " ["); for (i = 0; i < num; i++) { - string = get_string(fd, (void*)strarray[i], 0); + string = get_string(pid, (void*)strarray[i], 0); tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i+1 == num) ? ' ' : ','); free(string); } @@ -585,7 +574,7 @@ tmp = strdup(""); break; } - tmp2 = get_string(fd, (void*)args[sc->offset], retval); + tmp2 = get_string(pid, (void*)args[sc->offset], retval); asprintf(&tmp, "\"%s\"", tmp2); free(tmp2); } @@ -608,7 +597,7 @@ case Umtx: { struct umtx umtx; - if (get_struct(fd, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1) asprintf(&tmp, "{0x%lx}", (long)umtx.u_owner); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -617,7 +606,7 @@ case Timespec: { struct timespec ts; - if (get_struct(fd, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) asprintf(&tmp, "{%ld.%09ld}", (long)ts.tv_sec, ts.tv_nsec); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -626,7 +615,7 @@ case Timeval: { struct timeval tv; - if (get_struct(fd, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) asprintf(&tmp, "{%ld.%06ld}", (long)tv.tv_sec, tv.tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -635,7 +624,7 @@ case Timeval2: { struct timeval tv[2]; - if (get_struct(fd, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld}", (long)tv[0].tv_sec, tv[0].tv_usec, (long)tv[1].tv_sec, tv[1].tv_usec); @@ -646,7 +635,7 @@ case Itimerval: { struct itimerval itv; - if (get_struct(fd, (void *)args[sc->offset], &itv, sizeof(itv)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld}", (long)itv.it_interval.tv_sec, itv.it_interval.tv_usec, @@ -670,7 +659,7 @@ if ((pfd = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for pollfd array", bytes); - if (get_struct(fd, (void *)args[sc->offset], pfd, bytes) != -1) { + if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) { used = 0; tmpsize = 1 + per_fd * numfds + 2; @@ -709,7 +698,7 @@ if ((fds = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for fd_set array", bytes); - if (get_struct(fd, (void *)args[sc->offset], fds, bytes) != -1) { + if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) { used = 0; tmpsize = 1 + numfds * per_fd + 2; if ((tmp = malloc(tmpsize)) == NULL) @@ -749,7 +738,7 @@ int i, used; sig = args[sc->offset]; - if (get_struct(fd, (void *)args[sc->offset], (void *)&ss, + if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss)) == -1) { asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -853,7 +842,7 @@ } /* yuck: get ss_len */ - if (get_struct(fd, (void *)args[sc->offset], (void *)&ss, + if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) err(1, "get_struct %p", (void *)args[sc->offset]); /* @@ -874,7 +863,7 @@ break; } } - if (get_struct(fd, (void *)args[sc->offset], (void *)&ss, ss.ss_len) + if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len) == -1) { err(2, "get_struct %p", (void *)args[sc->offset]); } @@ -913,7 +902,7 @@ char *hand; const char *h; - if (get_struct(fd, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) { + if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) { asprintf(&hand, "%p", sa.sa_handler); if (sa.sa_handler == SIG_DFL) @@ -956,7 +945,7 @@ bytes = sizeof(struct kevent) * numevents; if ((ke = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for kevent array", bytes); - if (numevents >= 0 && get_struct(fd, (void *)args[sc->offset], ke, bytes) != -1) { + if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], ke, bytes) != -1) { used = 0; tmpsize = 1 + per_ke * numevents + 2; if ((tmp = malloc(tmpsize)) == NULL) @@ -986,7 +975,7 @@ case Stat: { struct stat st; - if (get_struct(fd, (void *)args[sc->offset], &st, sizeof(st)) != -1) { + if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) != -1) { char mode[12]; strmode(st.st_mode, mode); asprintf(&tmp, "{mode=%s,inode=%jd,size=%jd,blksize=%ld}", @@ -999,7 +988,7 @@ case Rusage: { struct rusage ru; - if (get_struct(fd, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) asprintf(&tmp, "{u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld}", (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, @@ -1011,7 +1000,7 @@ case Rlimit: { struct rlimit rl; - if (get_struct(fd, (void *)args[sc->offset], &rl, sizeof(rl)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) != -1) asprintf(&tmp, "{cur=%ju,max=%ju}", rl.rlim_cur, rl.rlim_max); else ==== //depot/vendor/freebsd/src/usr.bin/truss/truss.1#12 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/truss.1#3 (text+ko) ==== content @@ -23,7 +23,7 @@ utility traces the system calls called by the specified process or program. Output is to the specified output file, or standard error by default. It does this by stopping and restarting the process being monitored via -.Xr procfs 5 . +.Xr ptrace 2 . .Pp The options are as follows: .Bl -tag -width indent @@ -79,13 +79,6 @@ .Ar command options are mutually exclusive.) .El -.Pp -The -.Xr procctl 8 -utility can be used to clear tracepoints in a stuck process -left behind if -.Nm -terminates abnormally. .Sh EXAMPLES # Follow the system calls used in echoing "hello" .Dl $ truss /bin/echo hello @@ -96,8 +89,7 @@ .Sh SEE ALSO .Xr kdump 1 , .Xr ktrace 1 , -.Xr procfs 5 , -.Xr procctl 8 +.Xr ptrace 2 2 .Sh HISTORY The .Nm ==== //depot/vendor/freebsd/src/usr.bin/truss/truss.h#5 (text+ko) - //depot/user/howardsu/truss/usr.bin/truss/truss.h#4 (text+ko) ==== content @@ -25,6 +25,8 @@ * $FreeBSD: src/usr.bin/truss/truss.h,v 1.7 2006/05/15 21:18:28 pav Exp $ */ +#include + #define FOLLOWFORKS 0x00000001 #define RELATIVETIMESTAMPS 0x00000002 #define ABSOLUTETIMESTAMPS 0x00000004 @@ -32,17 +34,30 @@ #define EXECVEARGS 0x00000010 #define EXECVEENVS 0x00000020 +struct threadinfo +{ + SLIST_ENTRY(threadinfo) entries; + lwpid_t tid; + int in_syscall; + int in_fork; +}; + struct trussinfo { int pid; int flags; - int in_fork; + int pr_why; + int pr_data; int strsize; FILE *outfile; struct timespec start_time; struct timespec before; struct timespec after; + + struct threadinfo *curthread; + + SLIST_HEAD(, threadinfo) threadlist; }; #define timespecsubt(tvp, uvp, vvp) \ @@ -54,3 +69,10 @@ (vvp)->tv_nsec += 1000000000; \ } \ } while (0) + +#define S_NONE 0 +#define S_SCE 1 +#define S_SCX 2 +#define S_EXIT 3 +#define S_SIG 4 +#define S_EXEC 5