summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2007-04-10 04:03:34 +0000
committerdelphij <delphij@FreeBSD.org>2007-04-10 04:03:34 +0000
commit70cda62de51a69e83aae7565ff882b9edd048d14 (patch)
tree7ee5d84012b77bdd06777d2992c7aec9f559b5ce /usr.bin
parent96664c6737f5b26e562ce2c7fd207087f97ed9a7 (diff)
downloadFreeBSD-src-70cda62de51a69e83aae7565ff882b9edd048d14.zip
FreeBSD-src-70cda62de51a69e83aae7565ff882b9edd048d14.tar.gz
Make use of ptrace(2) instead of procfs in truss(1), eliminating
yet another need of an available /proc/ mount. Tested with: make universe Submitted by: howardsu Reviewed by: alfred
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/truss/Makefile2
-rw-r--r--usr.bin/truss/amd64-fbsd.c49
-rw-r--r--usr.bin/truss/amd64-fbsd32.c58
-rw-r--r--usr.bin/truss/amd64-linux32.c47
-rw-r--r--usr.bin/truss/extern.h4
-rw-r--r--usr.bin/truss/i386-fbsd.c58
-rw-r--r--usr.bin/truss/i386-linux.c47
-rw-r--r--usr.bin/truss/ia64-fbsd.c38
-rw-r--r--usr.bin/truss/main.c240
-rw-r--r--usr.bin/truss/powerpc-fbsd.c48
-rw-r--r--usr.bin/truss/setup.c220
-rw-r--r--usr.bin/truss/sparc64-fbsd.c51
-rw-r--r--usr.bin/truss/syscall.h3
-rw-r--r--usr.bin/truss/syscalls.c136
-rw-r--r--usr.bin/truss/truss.112
-rw-r--r--usr.bin/truss/truss.h24
16 files changed, 452 insertions, 585 deletions
diff --git a/usr.bin/truss/Makefile b/usr.bin/truss/Makefile
index 3fcc219..18c2b93 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 7c7a82e..dd00f59 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 7f049a6..f9e435d 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, &regs, sizeof(regs)) != sizeof(regs)) {
+
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 42b49ec..83f1505 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, &regs, sizeof(regs)) != sizeof(regs)) {
+
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
- fprintf(trussinfo->outfile, "\n");
+ cpid = trussinfo->curthread->tid;
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 ec47efe..3882f10 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 7f049a6..f9e435d 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, &regs, sizeof(regs)) != sizeof(regs)) {
+
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 42b49ec..83f1505 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, &regs, sizeof(regs)) != sizeof(regs)) {
+
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
- fprintf(trussinfo->outfile, "\n");
+ cpid = trussinfo->curthread->tid;
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 e233505..471e834 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 2096442..fa97020 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 179312a..5448a16 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 a6f8864..698d9f7 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 ff5073d..cc2f473 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, &regs, sizeof(regs)) != sizeof(regs)) {
+
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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, &regs, sizeof(regs)) != sizeof(regs)) {
+ if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 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 e7f6c3f..ccd83bb 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 33a1c0b..5eff8d6 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 7e8c5ec..133b87b 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 575260b..8533fae 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
OpenPOWER on IntegriCloud