diff options
author | Xin LI <delphij@FreeBSD.org> | 2007-04-10 04:03:34 +0000 |
---|---|---|
committer | Xin LI <delphij@FreeBSD.org> | 2007-04-10 04:03:34 +0000 |
commit | 5d2d083c921169fb83ad45fdae37fe3e14a9c895 (patch) | |
tree | 7ee5d84012b77bdd06777d2992c7aec9f559b5ce /usr.bin/truss | |
parent | 68bca8a5e315002b55a1ec7b173058f321cf74d2 (diff) | |
download | src-test2-5d2d083c921169fb83ad45fdae37fe3e14a9c895.tar.gz src-test2-5d2d083c921169fb83ad45fdae37fe3e14a9c895.zip |
Notes
Diffstat (limited to 'usr.bin/truss')
-rw-r--r-- | usr.bin/truss/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/truss/amd64-fbsd.c | 49 | ||||
-rw-r--r-- | usr.bin/truss/amd64-fbsd32.c | 58 | ||||
-rw-r--r-- | usr.bin/truss/amd64-linux32.c | 47 | ||||
-rw-r--r-- | usr.bin/truss/extern.h | 4 | ||||
-rw-r--r-- | usr.bin/truss/i386-fbsd.c | 58 | ||||
-rw-r--r-- | usr.bin/truss/i386-linux.c | 47 | ||||
-rw-r--r-- | usr.bin/truss/ia64-fbsd.c | 38 | ||||
-rw-r--r-- | usr.bin/truss/main.c | 240 | ||||
-rw-r--r-- | usr.bin/truss/powerpc-fbsd.c | 48 | ||||
-rw-r--r-- | usr.bin/truss/setup.c | 220 | ||||
-rw-r--r-- | usr.bin/truss/sparc64-fbsd.c | 51 | ||||
-rw-r--r-- | usr.bin/truss/syscall.h | 3 | ||||
-rw-r--r-- | usr.bin/truss/syscalls.c | 136 | ||||
-rw-r--r-- | usr.bin/truss/truss.1 | 12 | ||||
-rw-r--r-- | usr.bin/truss/truss.h | 24 |
16 files changed, 452 insertions, 585 deletions
diff --git a/usr.bin/truss/Makefile b/usr.bin/truss/Makefile index 3fcc219ceb38..18c2b932c677 100644 --- a/usr.bin/truss/Makefile +++ b/usr.bin/truss/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -WARNS?= 2 +WARNS?= 6 NO_WERROR= PROG= truss SRCS= main.c setup.c syscalls.c syscalls.h ioctl.c ${MACHINE_ARCH}-fbsd.c diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c index 7c7a82e22b39..dd00f595c23b 100644 --- a/usr.bin/truss/amd64-fbsd.c +++ b/usr.bin/truss/amd64-fbsd.c @@ -43,8 +43,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> @@ -63,7 +62,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -113,25 +111,16 @@ clear_fsc(void) { 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 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -181,8 +170,13 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { } } 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 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index 7f049a64c6e7..f9e435dd8631 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -43,9 +43,8 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> #include <sys/syscall.h> +#include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> @@ -63,7 +62,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -113,26 +111,18 @@ clear_fsc(void) { 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; - - 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; - } + struct ptrace_io_desc iorequest; + 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; } @@ -146,13 +136,11 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index 42b49ec7d4f5..83f15058a13f 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -41,8 +41,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> @@ -60,7 +59,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "linux_syscalls.h" @@ -108,28 +106,20 @@ clear_fsc(void) { 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 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { && ((!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 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ const int bsd_to_linux_errno[] = { 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; - } - - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { - fprintf(trussinfo->outfile, "\n"); + cpid = trussinfo->curthread->tid; + 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); @@ -313,7 +294,7 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h index ec47efeb8e9a..3882f1053cda 100644 --- a/usr.bin/truss/extern.h +++ b/usr.bin/truss/extern.h @@ -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 void sparc64_syscall_entry(struct trussinfo *, int); extern long sparc64_syscall_exit(struct trussinfo *, int); #endif -extern int Procfd; diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index 7f049a64c6e7..f9e435dd8631 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -43,9 +43,8 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> #include <sys/syscall.h> +#include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> @@ -63,7 +62,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -113,26 +111,18 @@ clear_fsc(void) { 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; - - 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; - } + struct ptrace_io_desc iorequest; + 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; } @@ -146,13 +136,11 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index 42b49ec7d4f5..83f15058a13f 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -41,8 +41,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <machine/reg.h> #include <machine/psl.h> @@ -60,7 +59,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "linux_syscalls.h" @@ -108,28 +106,20 @@ clear_fsc(void) { 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 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { && ((!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 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ const int bsd_to_linux_errno[] = { 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; - } - - lseek(fd, 0L, 0); - if (read(fd, ®s, sizeof(regs)) != sizeof(regs)) { - fprintf(trussinfo->outfile, "\n"); + cpid = trussinfo->curthread->tid; + 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); @@ -313,7 +294,7 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c index e233505ec951..471e83426247 100644 --- a/usr.bin/truss/ia64-fbsd.c +++ b/usr.bin/truss/ia64-fbsd.c @@ -43,8 +43,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> @@ -62,7 +61,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -112,26 +110,16 @@ clear_fsc(void) { 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->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; } @@ -158,7 +146,7 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -204,7 +192,7 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index 209644277198..fa9702092498 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -39,11 +39,10 @@ __FBSDID("$FreeBSD$"); */ #include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> +#include <sys/sysctl.h> #include <ctype.h> #include <err.h> @@ -59,12 +58,7 @@ __FBSDID("$FreeBSD$"); #include "truss.h" #include "extern.h" -/* - * It's difficult to parameterize this because it must be - * accessible in a signal handler. - */ - -int Procfd; +#define MAXARGS 5 static void usage(void) @@ -111,26 +105,26 @@ struct ex_types { /* * Set the execution type. This is called after every exec, and when - * a process is first monitored. The procfs pseudo-file "etype" has - * the execution module type -- see /proc/curproc/etype for an example. + * a process is first monitored. */ static struct ex_types * set_etype(struct trussinfo *trussinfo) { struct ex_types *funcs; - char etype[24]; char progt[32]; - int fd; - - 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); - } + + size_t len = sizeof(progt); + int mib[4]; + int error; + + 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 +161,12 @@ main(int ac, char **av) 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 +176,12 @@ main(int ac, char **av) 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 +240,7 @@ main(int ac, char **av) 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 +253,9 @@ main(int ac, char **av) */ 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)); - initial_open = 0; - if (Procfd == -1) - return (0); - - pfs.why = 0; - funcs = set_etype(trussinfo); + + initial_open = 0; /* * 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 +265,92 @@ START_TRACE: clock_gettime(CLOCK_REALTIME, &trussinfo->start_time); do { - int val = 0; struct timespec timediff; + waitevent(trussinfo); + + 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->curthread->in_fork && + (trussinfo->flags & FOLLOWFORKS)) { + int childpid; + + trussinfo->curthread->in_fork = 0; + childpid = + funcs->exit_syscall(trussinfo, + trussinfo->pr_data); - 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. + * Fork a new copy of ourself to trace + * the child of the original traced + * process. */ - if (in_exec) { - in_exec = 0; - break; - } - - if (trussinfo->in_fork && - (trussinfo->flags & FOLLOWFORKS)) { - int childpid; - - trussinfo->in_fork = 0; - childpid = - funcs->exit_syscall(trussinfo, - pfs.val); - - /* - * 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; + 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; - 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 (ioctl(Procfd, PIOCCONT, val) == -1) { - if (kill(trussinfo->pid, 0) == -1 && errno == ESRCH) + funcs->exit_syscall(trussinfo, MAXARGS); + break; + case S_SIG: + if (trussinfo->flags & NOSIGS) break; - else - warn("PIOCCONT"); + 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; } - } while (pfs.why != S_EXIT); + } while (trussinfo->pr_why != S_EXIT); fflush(trussinfo->outfile); if (sigexit) { struct rlimit rlp; @@ -400,5 +361,6 @@ START_TRACE: (void) signal(sigexit, SIG_DFL); (void) kill(getpid(), sigexit); } + return (0); } diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c index 179312a2186c..5448a168eef7 100644 --- a/usr.bin/truss/powerpc-fbsd.c +++ b/usr.bin/truss/powerpc-fbsd.c @@ -41,8 +41,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/reg.h> @@ -62,7 +61,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -120,19 +118,10 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -176,9 +165,16 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) 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; } } diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c index a6f88646504a..698d9f74b2a2 100644 --- a/usr.bin/truss/setup.c +++ b/usr.bin/truss/setup.c @@ -38,11 +38,12 @@ __FBSDID("$FreeBSD$"); */ #include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/types.h> +#include <sys/ptrace.h> #include <sys/wait.h> #include <err.h> +#include <errno.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> @@ -51,10 +52,12 @@ __FBSDID("$FreeBSD$"); #include <time.h> #include <unistd.h> +#include <machine/reg.h> + #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 @@ static int evflags = 0; 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 @@ setup_and_wait(char *command[]) */ int -start_tracing(int pid, int failisfatal, int eventflags, int flags) +start_tracing(int pid) { - int fd; - char buf[32]; - struct procfs_status tmp; - - sprintf(buf, "/proc/%d/mem", pid); - /* usleep(500000); */ - - 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); - } - - 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); + int waitval; + int ret; + int retry = 10; + + do { + ret = ptrace(PT_ATTACH, pid, NULL, 0); + usleep(200); + } while(ret && retry-- > 0); + if (ret) + err(1, "can not attach to target process"); + + child_pid = pid; + if (waitpid(pid, &waitval, 0) < -1) + err(1, "Unexpect stop in waitpid"); + + return (0); } /* @@ -193,10 +128,89 @@ start_tracing(int pid, int failisfatal, int eventflags, int flags) * process. */ void -restore_proc(int signo __unused) { +restore_proc(int signo __unused) +{ + int waitval; - ioctl(Procfd, PIOCBIC, ~0); - if (evflags) - ioctl(Procfd, PIOCBIS, evflags); + /* stop the child so that we can detach */ + kill(child_pid, SIGSTOP); + if (waitpid(child_pid, &waitval, 0) < -1) + err(1, "Unexpected stop in waitpid"); + + if (ptrace(PT_DETACH, child_pid, (caddr_t)1, 0) < 0) + err(1, "Can not detach the process"); + + kill(child_pid, SIGCONT); exit(0); } + +/* + * Change curthread member based on lwpid. + * If it is a new thread, create a threadinfo structure + */ +static 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; +} + +/* + * Start the traced process and wait until it stoped. + * Fill trussinfo structure. + * When this even returns, the traced process is in stop state. + */ +void +waitevent(struct trussinfo *info) +{ + int waitval; + static int pending_signal = 0; + + ptrace(PT_SYSCALL, info->pid, (caddr_t)1, pending_signal); + pending_signal = 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); + pending_signal = info->pr_data; + break; + } + } +} diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c index ff5073d8148b..cc2f473fa849 100644 --- a/usr.bin/truss/sparc64-fbsd.c +++ b/usr.bin/truss/sparc64-fbsd.c @@ -45,8 +45,7 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/syscall.h> #include <machine/frame.h> @@ -68,7 +67,6 @@ static const char rcsid[] = #include "syscall.h" #include "extern.h" -static int fd = -1; static int cpid = -1; #include "syscalls.h" @@ -118,26 +116,18 @@ clear_fsc(void) { 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 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { - trussinfo->in_fork = 1; + trussinfo->curthread->in_fork = 1; } if (nargs == 0) @@ -186,9 +176,14 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { * 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 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { 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 @@ -295,25 +290,15 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { long sparc64_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); } @@ -344,7 +329,7 @@ sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { 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; } } diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index e7f6c3ff43f5..ccd83bb512c7 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -60,8 +60,7 @@ struct syscall { }; 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); diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 33a1c0b935f4..5eff8d663ca9 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -41,6 +41,7 @@ static const char rcsid[] = #include <sys/mman.h> #include <sys/types.h> +#include <sys/ptrace.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/un.h> @@ -216,7 +217,7 @@ struct syscall syscalls[] = { /* Xlat idea taken from strace */ struct xlat { int val; - char *str; + const char *str; }; #define X(a) { a, #a }, @@ -324,7 +325,8 @@ static struct xlat pathconf_arg[] = { /* Searches an xlat array for a value, and returns it if found. Otherwise return a string representation. */ -char *lookup(struct xlat *xlat, int val, int base) +static const char +*lookup(struct xlat *xlat, int val, int base) { static char tmp[16]; for (; xlat->str != NULL; xlat++) @@ -347,7 +349,8 @@ char *lookup(struct xlat *xlat, int val, int base) return tmp; } -char *xlookup(struct xlat *xlat, int val) +static const char * +xlookup(struct xlat *xlat, int val) { return lookup(xlat, val, 16); } @@ -355,7 +358,8 @@ char *xlookup(struct xlat *xlat, int val) /* Searches an xlat array containing bitfield values. Remaining bits set after removing the known ones are printed at the end: IN|0x400 */ -char *xlookup_bits(struct xlat *xlat, int val) +static char +*xlookup_bits(struct xlat *xlat, int val) { static char str[512]; int len = 0; @@ -408,13 +412,20 @@ get_syscall(const char *name) { */ static int -get_struct(int procfd, void *offset, void *buf, int len) { - - if (pread(procfd, buf, len, (uintptr_t)offset) != len) - return -1; +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) < 0) + return -1; return 0; } +#define MAXSIZE 4096 +#define BLOCKSIZE 1024 /* * get_string * Copy a string from the process. Note that it is @@ -422,39 +433,42 @@ get_struct(int procfd, void *offset, void *buf, int len) { * only get that much. */ -char * -get_string(int procfd, void *offset, int max) { +static char * +get_string(pid_t pid, void *offset, int max) { char *buf; - int size, len, c, fd; - FILE *p; - - 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; - } + struct ptrace_io_desc iorequest; + int totalsize, size; + int diff = 0; + int i; + + totalsize = size = max ? (max + 1) : BLOCKSIZE; + buf = malloc(totalsize); + if (buf == NULL) + return NULL; + for(;;) { + diff = totalsize - size; + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (char *)offset + diff; + iorequest.piod_addr = buf + diff; + iorequest.piod_len = size; + if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { + free(buf); + return NULL; + } + for (i = 0 ; i < size; i++) { + if (buf[diff + i] == '\0') + return (buf); + } + if (totalsize < MAXSIZE - BLOCKSIZE && max == 0) { + totalsize += BLOCKSIZE; + buf = realloc(buf, totalsize); + size = BLOCKSIZE; + } + else { + buf[totalsize] = '\0'; + return buf; } - buf[len] = 0; } - fclose(p); - return (buf); } @@ -469,9 +483,9 @@ get_string(int procfd, void *offset, int max) { */ 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 +500,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str { /* 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 +528,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +549,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +558,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str /* 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 +569,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +599,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +622,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +631,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +640,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +649,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +660,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +684,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +723,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +763,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +867,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str } /* 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 +888,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +927,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +970,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +1000,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +1013,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 +1025,7 @@ print_arg(int fd, struct syscall_args *sc, unsigned long *args, long retval, str 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 diff --git a/usr.bin/truss/truss.1 b/usr.bin/truss/truss.1 index 7e8c5ecb0130..133b87b5c945 100644 --- a/usr.bin/truss/truss.1 +++ b/usr.bin/truss/truss.1 @@ -23,7 +23,7 @@ The 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 @@ and .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 @@ terminates abnormally. .Sh SEE ALSO .Xr kdump 1 , .Xr ktrace 1 , -.Xr procfs 5 , -.Xr procctl 8 +.Xr ptrace 2 2 .Sh HISTORY The .Nm diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h index 575260b193d2..8533fae36ea9 100644 --- a/usr.bin/truss/truss.h +++ b/usr.bin/truss/truss.h @@ -25,6 +25,8 @@ * $FreeBSD$ */ +#include <sys/queue.h> + #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 @@ struct trussinfo (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 |