[Review] Remove procfs dependency of truss

Howard Su howard0su at gmail.com
Wed Apr 4 08:46:36 UTC 2007


Following the suggestion in idea page, I proposed the attached patch.
I didn't change any kernel part because I think PTRACE(2) is
functional although man page didn't document it.

I tested the patch under i386 and amd64 box. The help on testing and
code review will be appreciated.

To test, please try the following commands:
1. truss ps
basic stuff
2. truss -o output ps
output the result to file
3. truss -f -o output sh -c "ps"
test follow fork
4. start TOP(1) in another session, the
truss -p <pid_of_top>

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


More information about the freebsd-current mailing list