[Midnightbsd-cvs] src [8144] trunk/usr.bin/truss: - Use pid_t type instead of just int.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Sep 16 18:14:07 EDT 2016


Revision: 8144
          http://svnweb.midnightbsd.org/src/?rev=8144
Author:   laffer1
Date:     2016-09-16 18:14:07 -0400 (Fri, 16 Sep 2016)
Log Message:
-----------
- Use pid_t type instead of just int.

- Put arguments for print_syscall_ret() function in proper order.
  Bug was introduced in r192025.

- Remove unused variables.
- Fix warnings about comparing signed and unsigned ints.

- Style(9) cleanup.

- Remove unused variables.
- Remove redundant return after err(3) call.

- Fix detaching under some circumstances.

  When truss is detaching from very active process it is possible to
  hang on waitpid(2) in restore_proc() forever, because
  ptrace(PT_SYSCALL) must be called before detaching, to allow the
  debugging process to continue execution.  Also when truss called with
  '-c' argument, it does not print anything after detach, because it
  immediately exits from restore_proc().

  To fix these two problems make detaching deferred, but then it is
  impossible to detach from a process which does not do any system call.
  To fix this issue use sigaction(2) instead of signal(3) to disable
  SA_RESTART flag for waitpid(2) that makes it non-restartable.  Remove
  global variable child_pid, because now detaching is handled in context
  where child's pid is known.

- Make truss thread-aware.

Revision Links:
--------------
    http://svnweb.midnightbsd.org/src/?rev=192025

Modified Paths:
--------------
    trunk/usr.bin/truss/amd64-fbsd.c
    trunk/usr.bin/truss/amd64-fbsd32.c
    trunk/usr.bin/truss/amd64-linux32.c
    trunk/usr.bin/truss/extern.h
    trunk/usr.bin/truss/i386-fbsd.c
    trunk/usr.bin/truss/i386-linux.c
    trunk/usr.bin/truss/ia64-fbsd.c
    trunk/usr.bin/truss/main.c
    trunk/usr.bin/truss/mips-fbsd.c
    trunk/usr.bin/truss/powerpc-fbsd.c
    trunk/usr.bin/truss/powerpc64-fbsd.c
    trunk/usr.bin/truss/setup.c
    trunk/usr.bin/truss/sparc64-fbsd.c
    trunk/usr.bin/truss/syscall.h
    trunk/usr.bin/truss/syscalls.c
    trunk/usr.bin/truss/truss.h

Modified: trunk/usr.bin/truss/amd64-fbsd.c
===================================================================
--- trunk/usr.bin/truss/amd64-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/amd64-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -62,8 +62,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -77,7 +75,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -84,22 +82,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -110,147 +114,147 @@
  */
 
 void
-amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i, reg;
-  struct syscall *sc;
+amd64_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	int i, reg, syscall_num;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  reg = 0;
-  syscall_num = regs.r_rax;
-  switch (syscall_num) {
-  case SYS_syscall:
-  case SYS___syscall:
-    syscall_num = regs.r_rdi;
-    reg++;
-    break;
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	reg = 0;
+	syscall_num = regs.r_rax;
+	switch (syscall_num) {
+	case SYS_syscall:
+	case SYS___syscall:
+		syscall_num = regs.r_rdi;
+		reg++;
+		break;
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ?  NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
-  for (i = 0; i < nargs && reg < 6; i++, reg++) {
-    switch (reg) {
-    case 0: fsc.args[i] = regs.r_rdi; break;
-    case 1: fsc.args[i] = regs.r_rsi; break;
-    case 2: fsc.args[i] = regs.r_rdx; break;
-    case 3: fsc.args[i] = regs.r_rcx; break;
-    case 4: fsc.args[i] = regs.r_r8; break;
-    case 5: fsc.args[i] = regs.r_r9; break;
-    }
-  }
-  if (nargs > i) {
-    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;
-  }
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+	for (i = 0; i < nargs && reg < 6; i++, reg++) {
+		switch (reg) {
+		case 0: fsc->args[i] = regs.r_rdi; break;
+		case 1: fsc->args[i] = regs.r_rsi; break;
+		case 2: fsc->args[i] = regs.r_rdx; break;
+		case 3: fsc->args[i] = regs.r_rcx; break;
+		case 4: fsc->args[i] = regs.r_r8; break;
+		case 5: fsc->args[i] = regs.r_r9; break;
+		}
+	}
+	if (nargs > i) {
+		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, tid, (caddr_t)&iorequest, 0);
+		if (iorequest.piod_len == 0)
+			return;
+	}
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%lx%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%lx%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -263,68 +267,72 @@
 long
 amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-    return (-1);
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  cpid = trussinfo->curthread->tid;
+	tid = 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_rax;
-  errorp = !!(regs.r_rflags & PSL_C);
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	retval = regs.r_rax;
+	errorp = !!(regs.r_rflags & PSL_C);
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/amd64-fbsd32.c
===================================================================
--- trunk/usr.bin/truss/amd64-fbsd32.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/amd64-fbsd32.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -43,8 +43,8 @@
  */
 
 #include <sys/types.h>
+#include <sys/ptrace.h>
 #include <sys/syscall.h>
-#include <sys/ptrace.h>
 
 #include <machine/reg.h>
 #include <machine/psl.h>
@@ -62,8 +62,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "freebsd32_syscalls.h"
 
 static int nsyscalls = sizeof(freebsd32_syscallnames) /
@@ -78,7 +76,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd32_syscall {
+struct freebsd32_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -86,25 +84,29 @@
 	unsigned int *args32;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd32_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd32_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.args32) {
-    free(fsc.args32);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd32_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	free(fsc->args32);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -115,145 +117,145 @@
  */
 
 void
-amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  unsigned long parm_offset;
-  struct syscall *sc = NULL;
-  struct ptrace_io_desc iorequest;
-  cpid = trussinfo->curthread->tid;
+amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd32_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	unsigned long parm_offset;
+	int i, syscall_num;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
-  parm_offset = regs.r_rsp + sizeof(int);
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  syscall_num = regs.r_rax;
-  switch (syscall_num) {
-  case SYS_syscall:
-    syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0);
-    parm_offset += sizeof(int);
-    break;
-  case SYS___syscall:
-    syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0);
-    parm_offset += sizeof(quad_t);
-    break;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
+	parm_offset = regs.r_rsp + sizeof(int);
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL :
-      freebsd32_syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	syscall_num = regs.r_rax;
+	switch (syscall_num) {
+	case SYS_syscall:
+		syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0);
+		parm_offset += sizeof(int);
+		break;
+	case SYS___syscall:
+		syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0);
+		parm_offset += sizeof(quad_t);
+		break;
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : freebsd32_syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (nargs == 0)
-    return;
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  fsc.args32 = malloc((1+nargs) * sizeof(unsigned int));
-  iorequest.piod_op = PIOD_READ_D;
-  iorequest.piod_offs = (void *)parm_offset;
-  iorequest.piod_addr = fsc.args32;
-  iorequest.piod_len = (1+nargs) * sizeof(unsigned int);
-  ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0);
-  if (iorequest.piod_len == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
-  for (i = 0; i < nargs + 1; i++) 
-     fsc.args[i] = fsc.args32[i];
+	fsc->args32 = malloc((1 + nargs) * sizeof(unsigned int));
+	iorequest.piod_op = PIOD_READ_D;
+	iorequest.piod_offs = (void *)parm_offset;
+	iorequest.piod_addr = fsc->args32;
+	iorequest.piod_len = (1 + nargs) * sizeof(unsigned int);
+	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+	if (iorequest.piod_len == 0)
+		return;
 
-  if (fsc.name)
-  	sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+	for (i = 0; i < nargs + 1; i++)
+		 fsc->args[i] = fsc->args32[i];
+
+	sc = NULL;
+	if (fsc->name)
+		sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "freebsd32_execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "freebsd32_execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "freebsd32_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "freebsd32_execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -266,68 +268,72 @@
 long
 amd64_fbsd32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd32_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-    return (-1);
-  cpid = trussinfo->curthread->tid;
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return (-1);
-  }
-  
-  retval = regs.r_rax;
-  errorp = !!(regs.r_rflags & PSL_C);
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
+	retval = regs.r_rax;
+	errorp = !!(regs.r_rflags & PSL_C);
+
 	/*
-	 * If an error occurred, then don't bother getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "freebsd32_execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	if (fsc->name != NULL && (strcmp(fsc->name, "freebsd32_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/amd64-linux32.c
===================================================================
--- trunk/usr.bin/truss/amd64-linux32.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/amd64-linux32.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -59,8 +59,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "linux32_syscalls.h"
 
 static int nsyscalls =
@@ -75,7 +73,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct linux_syscall {
+struct linux_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -82,19 +80,27 @@
 	unsigned long args[5];
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct linux_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct linux_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct linux_syscall *fsc)
+{
+	int i;
+
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -105,124 +111,125 @@
  */
 
 void
-amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  struct syscall *sc;
+amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct reg regs;
+	struct linux_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	int i, syscall_num;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  } 
-  syscall_num = regs.r_rax;
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : linux32_syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	syscall_num = regs.r_rax;
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "linux_fork")
-    || !strcmp(fsc.name, "linux_vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : linux32_syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (nargs == 0)
-    return;
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "linux_fork") == 0 ||
+	    strcmp(fsc->name, "linux_vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  /*
-   * Linux passes syscall arguments in registers, not
-   * on the stack.  Fortunately, we've got access to the
-   * register set.  Note that we don't bother checking the
-   * number of arguments.  And what does linux do for syscalls
-   * that have more than five arguments?
-   */
+	if (nargs == 0)
+		return;
 
-  fsc.args[0] = regs.r_rbx;
-  fsc.args[1] = regs.r_rcx;
-  fsc.args[2] = regs.r_rdx;
-  fsc.args[3] = regs.r_rsi;
-  fsc.args[4] = regs.r_rdi;
+	/*
+	 * Linux passes syscall arguments in registers, not
+	 * on the stack.  Fortunately, we've got access to the
+	 * register set.  Note that we don't bother checking the
+	 * number of arguments.	And what does linux do for syscalls
+	 * that have more than five arguments?
+	 */
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	fsc->args[0] = regs.r_rbx;
+	fsc->args[1] = regs.r_rcx;
+	fsc->args[2] = regs.r_rdx;
+	fsc->args[3] = regs.r_rsi;
+	fsc->args[4] = regs.r_rdi;
+
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "linux_execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "linux_execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -229,87 +236,94 @@
  * Linux syscalls return negative errno's, we do positive and map them
  */
 const int bsd_to_linux_errno[] = {
-  	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
- 	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
- 	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
- 	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
- 	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
+	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
 	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
 	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
 	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
-  	-6, 
+	-6,
 };
 
 long
-amd64_linux32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
+amd64_linux32_syscall_exit(struct trussinfo *trussinfo,
+    int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct linux_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  cpid = trussinfo->curthread->tid;
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return (-1);
-  }
+	tid = trussinfo->curthread->tid;
 
-  retval = regs.r_rax;
-  errorp = !!(regs.r_rflags & PSL_C);
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	retval = regs.r_rax;
+	errorp = !!(regs.r_rflags & PSL_C);
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
-  if (errorp) {
-    for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++)
-      if (retval == bsd_to_linux_errno[i])
-      break;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
+	if (errorp) {
+		for (i = 0;
+		    (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) {
+			if (retval == bsd_to_linux_errno[i])
+				break;
+		}
+	}
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-                    errorp ? i : retval, fsc.sc);
-  clear_fsc();
+	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    errorp ? i : retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/extern.h
===================================================================
--- trunk/usr.bin/truss/extern.h	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/extern.h	2016-09-16 22:14:07 UTC (rev 8144)
@@ -32,7 +32,7 @@
  */
 
 extern int setup_and_wait(char **);
-extern int start_tracing(int);
+extern int start_tracing(pid_t);
 extern void restore_proc(int);
 extern void waitevent(struct trussinfo *);
 extern const char *ioctlname(register_t val);

Modified: trunk/usr.bin/truss/i386-fbsd.c
===================================================================
--- trunk/usr.bin/truss/i386-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/i386-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -43,8 +43,8 @@
  */
 
 #include <sys/types.h>
+#include <sys/ptrace.h>
 #include <sys/syscall.h>
-#include <sys/ptrace.h>
 
 #include <machine/reg.h>
 #include <machine/psl.h>
@@ -62,8 +62,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -77,7 +75,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -84,22 +82,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -110,140 +114,141 @@
  */
 
 void
-i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  unsigned int parm_offset;
-  struct syscall *sc = NULL;
-  struct ptrace_io_desc iorequest;
-  cpid = trussinfo->curthread->tid;
+i386_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	unsigned int parm_offset;
+	int i, syscall_num;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
-  parm_offset = regs.r_esp + sizeof(int);
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  syscall_num = regs.r_eax;
-  switch (syscall_num) {
-  case SYS_syscall:
-    syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0);
-    parm_offset += sizeof(int);
-    break;
-  case SYS___syscall:
-    syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0);
-    parm_offset += sizeof(quad_t);
-    break;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
+	parm_offset = regs.r_esp + sizeof(int);
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	syscall_num = regs.r_eax;
+	switch (syscall_num) {
+	case SYS_syscall:
+		syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0);
+		parm_offset += sizeof(int);
+		break;
+	case SYS___syscall:
+		syscall_num = ptrace(PT_READ_D, tid, (caddr_t)parm_offset, 0);
+		parm_offset += sizeof(quad_t);
+		break;
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (nargs == 0)
-    return;
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
-  iorequest.piod_op = PIOD_READ_D;
-  iorequest.piod_offs = (void *)parm_offset;
-  iorequest.piod_addr = fsc.args;
-  iorequest.piod_len = (1+nargs) * sizeof(unsigned long);
-  ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0);
-  if (iorequest.piod_len == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  if (fsc.name)
-  	sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+	iorequest.piod_op = PIOD_READ_D;
+	iorequest.piod_offs = (void *)parm_offset;
+	iorequest.piod_addr = fsc->args;
+	iorequest.piod_len = (1 + nargs) * sizeof(unsigned long);
+	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+	if (iorequest.piod_len == 0)
+		return;
+
+	sc = NULL;
+	if (fsc->name)
+		sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -256,68 +261,72 @@
 long
 i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-    return (-1);
-  cpid = trussinfo->curthread->tid;
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  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);
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
+	retval = regs.r_eax;
+	errorp = !!(regs.r_eflags & PSL_C);
+
 	/*
-	 * If an error occurred, then don't bother getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/i386-linux.c
===================================================================
--- trunk/usr.bin/truss/i386-linux.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/i386-linux.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -59,8 +59,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "linux_syscalls.h"
 
 static int nsyscalls =
@@ -75,7 +73,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct linux_syscall {
+struct linux_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -82,19 +80,27 @@
 	unsigned long args[5];
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct linux_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct linux_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct linux_syscall *fsc)
+{
+	int i;
+
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -105,124 +111,125 @@
  */
 
 void
-i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  struct syscall *sc;
+i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct reg regs;
+	struct linux_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	int i, syscall_num;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  } 
-  syscall_num = regs.r_eax;
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : linux_syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	syscall_num = regs.r_eax;
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "linux_fork")
-    || !strcmp(fsc.name, "linux_vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : linux_syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (nargs == 0)
-    return;
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "linux_fork") == 0 ||
+	    strcmp(fsc->name, "linux_vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  /*
-   * Linux passes syscall arguments in registers, not
-   * on the stack.  Fortunately, we've got access to the
-   * register set.  Note that we don't bother checking the
-   * number of arguments.  And what does linux do for syscalls
-   * that have more than five arguments?
-   */
+	if (nargs == 0)
+		return;
 
-  fsc.args[0] = regs.r_ebx;
-  fsc.args[1] = regs.r_ecx;
-  fsc.args[2] = regs.r_edx;
-  fsc.args[3] = regs.r_esi;
-  fsc.args[4] = regs.r_edi;
+	/*
+	 * Linux passes syscall arguments in registers, not
+	 * on the stack.  Fortunately, we've got access to the
+	 * register set.  Note that we don't bother checking the
+	 * number of arguments.	And what does linux do for syscalls
+	 * that have more than five arguments?
+	 */
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	fsc->args[0] = regs.r_ebx;
+	fsc->args[1] = regs.r_ecx;
+	fsc->args[2] = regs.r_edx;
+	fsc->args[3] = regs.r_esi;
+	fsc->args[4] = regs.r_edi;
+
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "linux_execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "linux_execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -229,87 +236,93 @@
  * Linux syscalls return negative errno's, we do positive and map them
  */
 const int bsd_to_linux_errno[] = {
-  	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
- 	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
- 	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
- 	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
- 	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
+	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
 	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
 	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
 	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
-  	-6, 
+	-6,
 };
 
 long
 i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct linux_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  cpid = trussinfo->curthread->tid;
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
-  {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return (-1);
-  }
+	tid = trussinfo->curthread->tid;
 
-  retval = regs.r_eax;
-  errorp = !!(regs.r_eflags & PSL_C);
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	retval = regs.r_eax;
+	errorp = !!(regs.r_eflags & PSL_C);
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
-  if (errorp) {
-    for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++)
-      if (retval == bsd_to_linux_errno[i])
-      break;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
+	if (errorp) {
+		for (i = 0;
+		    (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) {
+			if (retval == bsd_to_linux_errno[i])
+				break;
+		}
+	}
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-                    errorp ? i : retval, fsc.sc);
-  clear_fsc();
+	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    errorp ? i : retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/ia64-fbsd.c
===================================================================
--- trunk/usr.bin/truss/ia64-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/ia64-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -61,8 +61,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -76,7 +74,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -83,22 +81,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -109,122 +113,124 @@
  */
 
 void
-ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  unsigned long *parm_offset;
-  struct syscall *sc;
+ia64_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	unsigned long *parm_offset;
+	lwpid_t tid;
+	int i, syscall_num;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
-  parm_offset = &regs.r_scratch.gr16;
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
+	parm_offset = &regs.r_scratch.gr16;
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  syscall_num = regs.r_scratch.gr15;		/* XXX double-check. */
-  if (syscall_num == SYS_syscall || syscall_num == SYS___syscall)
-    syscall_num = (int)*parm_offset++;
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	syscall_num = regs.r_scratch.gr15;	/* XXX double-check. */
+	if (syscall_num == SYS_syscall || syscall_num == SYS___syscall)
+		syscall_num = (int)*parm_offset++;
 
-  fsc.number = syscall_num;
-  fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls)
-      ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
-  memcpy(fsc.args, parm_offset, nargs * sizeof(long));
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+	memcpy(fsc->args, parm_offset, nargs * sizeof(long));
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -237,65 +243,72 @@
 long
 ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
-  cpid = trussinfo->curthread->tid;
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return (-1);
-  }
-  retval = regs.r_scratch.gr8;
-  errorp = (regs.r_scratch.gr10 != 0) ? 1 : 0;
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return (-1);
+	}
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
+	retval = regs.r_scratch.gr8;
+	errorp = (regs.r_scratch.gr10 != 0) ? 1 : 0;
+
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    fsc.sc, retval);
-  clear_fsc();
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  return (retval);
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
+
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/main.c
===================================================================
--- trunk/usr.bin/truss/main.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/main.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -59,7 +59,7 @@
 #include "extern.h"
 #include "syscall.h"
 
-#define MAXARGS 6
+#define	MAXARGS	6
 
 static void
 usage(void)
@@ -113,7 +113,7 @@
 
 /*
  * Set the execution type.  This is called after every exec, and when
- * a process is first monitored. 
+ * a process is first monitored.
  */
 
 static struct ex_types *
@@ -120,12 +120,12 @@
 set_etype(struct trussinfo *trussinfo)
 {
 	struct ex_types *funcs;
+	size_t len;
+	int error;
+	int mib[4];
 	char progt[32];
-	
-	size_t len = sizeof(progt);
-	int mib[4];
-	int error;
 
+	len = sizeof(progt);
 	mib[0] = CTL_KERN;
 	mib[1] = KERN_PROC;
 	mib[2] = KERN_PROC_SV_NAME;
@@ -135,7 +135,7 @@
 		err(2, "can not get etype");
 
 	for (funcs = ex_types; funcs->type; funcs++)
-		if (!strcmp(funcs->type, progt))
+		if (strcmp(funcs->type, progt) == 0)
 			break;
 
 	if (funcs->type == NULL) {
@@ -163,16 +163,15 @@
 int
 main(int ac, char **av)
 {
-	int c;
-	int i;
-	pid_t childpid;
-	int status;
-	char **command;
+	struct timespec timediff;
+	struct sigaction sa;
 	struct ex_types *funcs;
-	int initial_open;
+	struct trussinfo *trussinfo;
 	char *fname;
-	struct trussinfo *trussinfo;
 	char *signame;
+	char **command;
+	pid_t childpid;
+	int c, initial_open, status;
 
 	fname = NULL;
 	initial_open = 1;
@@ -192,7 +191,7 @@
 		case 'p':	/* specified pid */
 			trussinfo->pid = atoi(optarg);
 			/* make sure i don't trace me */
-			if(trussinfo->pid == getpid()) {
+			if (trussinfo->pid == getpid()) {
 				fprintf(stderr, "attempt to grab self.\n");
 				exit(2);
 			}
@@ -221,7 +220,7 @@
 		case 's':	/* Specified string size */
 			trussinfo->strsize = atoi(optarg);
 			break;
-		case 'S':	/* Don't trace signals */ 
+		case 'S':	/* Don't trace signals */
 			trussinfo->flags |= NOSIGS;
 			break;
 		default:
@@ -260,10 +259,13 @@
 		signal(SIGTERM, SIG_IGN);
 		signal(SIGQUIT, SIG_IGN);
 	} else {
+		sa.sa_handler = restore_proc;
+		sa.sa_flags = 0;
+		sigemptyset(&sa.sa_mask);
+		sigaction(SIGINT, &sa, NULL);
+		sigaction(SIGQUIT, &sa, NULL);
+		sigaction(SIGTERM, &sa, NULL);
 		start_tracing(trussinfo->pid);
-		signal(SIGINT, restore_proc);
-		signal(SIGTERM, restore_proc);
-		signal(SIGQUIT, restore_proc);
 	}
 
 
@@ -285,25 +287,23 @@
 	clock_gettime(CLOCK_REALTIME, &trussinfo->start_time);
 
 	do {
-		struct timespec timediff;
 		waitevent(trussinfo);
 
-		switch(i = trussinfo->pr_why) {
+		switch (trussinfo->pr_why) {
 		case S_SCE:
 			funcs->enter_syscall(trussinfo, MAXARGS);
 			clock_gettime(CLOCK_REALTIME,
-			    &trussinfo->before);
+			    &trussinfo->curthread->before);
 			break;
 		case S_SCX:
 			clock_gettime(CLOCK_REALTIME,
-			    &trussinfo->after);
+			    &trussinfo->curthread->after);
 
 			if (trussinfo->curthread->in_fork &&
 			    (trussinfo->flags & FOLLOWFORKS)) {
 				trussinfo->curthread->in_fork = 0;
-				childpid =
-				    funcs->exit_syscall(trussinfo,
-					trussinfo->pr_data);
+				childpid = funcs->exit_syscall(trussinfo,
+				    trussinfo->pr_data);
 
 				/*
 				 * Fork a new copy of ourself to trace
@@ -326,7 +326,7 @@
 				fprintf(trussinfo->outfile, "%5d: ",
 				    trussinfo->pid);
 			if (trussinfo->flags & ABSOLUTETIMESTAMPS) {
-				timespecsubt(&trussinfo->after,
+				timespecsubt(&trussinfo->curthread->after,
 				    &trussinfo->start_time, &timediff);
 				fprintf(trussinfo->outfile, "%ld.%09ld ",
 				    (long)timediff.tv_sec,
@@ -333,8 +333,8 @@
 				    timediff.tv_nsec);
 			}
 			if (trussinfo->flags & RELATIVETIMESTAMPS) {
-				timespecsubt(&trussinfo->after,
-				    &trussinfo->before, &timediff);
+				timespecsubt(&trussinfo->curthread->after,
+				    &trussinfo->curthread->before, &timediff);
 				fprintf(trussinfo->outfile, "%ld.%09ld ",
 				    (long)timediff.tv_sec,
 				    timediff.tv_nsec);
@@ -352,7 +352,7 @@
 				fprintf(trussinfo->outfile, "%5d: ",
 				    trussinfo->pid);
 			if (trussinfo->flags & ABSOLUTETIMESTAMPS) {
-				timespecsubt(&trussinfo->after,
+				timespecsubt(&trussinfo->curthread->after,
 				    &trussinfo->start_time, &timediff);
 				fprintf(trussinfo->outfile, "%ld.%09ld ",
 				    (long)timediff.tv_sec,
@@ -359,10 +359,10 @@
 				    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);
+				timespecsubt(&trussinfo->curthread->after,
+				    &trussinfo->curthread->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);
@@ -370,15 +370,17 @@
 		default:
 			break;
 		}
-	} while (trussinfo->pr_why != S_EXIT);
+	} while (trussinfo->pr_why != S_EXIT &&
+	    trussinfo->pr_why != S_DETACHED);
 
-	if (trussinfo->flags & FOLLOWFORKS)
+	if (trussinfo->flags & FOLLOWFORKS) {
 		do {
 			childpid = wait(&status);
 		} while (childpid != -1);
+	}
 
- 	if (trussinfo->flags & COUNTONLY)
- 		print_summary(trussinfo);
+	if (trussinfo->flags & COUNTONLY)
+		print_summary(trussinfo);
 
 	fflush(trussinfo->outfile);
 

Modified: trunk/usr.bin/truss/mips-fbsd.c
===================================================================
--- trunk/usr.bin/truss/mips-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/mips-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -66,8 +66,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -81,7 +79,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -88,22 +86,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -114,162 +118,171 @@
  */
 
 void
-mips_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  struct syscall *sc;
-  int indir = 0;	/* indirect system call */
-  struct ptrace_io_desc iorequest;
+mips_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	int i, syscall_num;
+	int indir;	/* indirect system call */
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  syscall_num = regs.r_regs[V0];
-  if (syscall_num == SYS_syscall) {
-    indir = 1;
-    syscall_num = regs.r_regs[A0];
-  }
+	indir = 0;
+	syscall_num = regs.r_regs[V0];
+	if (syscall_num == SYS_syscall) {
+		indir = 1;
+		syscall_num = regs.r_regs[A0];
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
 #if 0 // XXX
-  iorequest.piod_op = PIOD_READ_D;
-  iorequest.piod_offs = (void *)parm_offset;
-  iorequest.piod_addr = fsc.args;
-  iorequest.piod_len = (1+nargs) * sizeof(unsigned long);
-  ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0);
-  if (iorequest.piod_len == 0)
-    return;
+	iorequest.piod_op = PIOD_READ_D;
+	iorequest.piod_offs = (void *)parm_offset;
+	iorequest.piod_addr = fsc->args;
+	iorequest.piod_len = (1 + nargs) * sizeof(unsigned long);
+	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+	if (iorequest.piod_len == 0)
+		return;
 #else
-  iorequest.piod_op = PIOD_READ_D;
+	iorequest.piod_op = PIOD_READ_D;
 #endif
 
-  switch (nargs) {
-  default:
-	/*
-	 * The OS doesn't seem to allow more than 10 words of
-	 * parameters (yay!).  So we shouldn't be here.
-	 */
-	warn("More than 10 words (%d) of arguments!\n", nargs);
-	break;
-  case 10: case 9: case 8: case 7: case 6: case 5:
-	/*
-	 * If there are 7-10 words of arguments, they are placed
-	 * on the stack, as is normal for other processors.
-	 * The fall-through for all of these is deliberate!!!
-	 */
-	  // XXX BAD constant used here
-	iorequest.piod_op = PIOD_READ_D;
-	iorequest.piod_offs = (void *)(regs.r_regs[SP] + 4 * sizeof(uint32_t));
-	iorequest.piod_addr = &fsc.args[4];
-	iorequest.piod_len = (nargs - 4) * sizeof(fsc.args[0]);
-	ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0);
-	if (iorequest.piod_len == 0) return;
-  case 4:	fsc.args[3] = regs.r_regs[A3];
-  case 3:	fsc.args[2] = regs.r_regs[A2];
-  case 2:	fsc.args[1] = regs.r_regs[A1];
-  case 1:	fsc.args[0] = regs.r_regs[A0];
-  case 0:
-	break;
-  }
-  if (indir) {
-    memmove(&fsc.args[0], &fsc.args[1], (nargs-1) * sizeof(fsc.args[0]));
-  }
+	switch (nargs) {
+	default:
+		/*
+		 * The OS doesn't seem to allow more than 10 words of
+		 * parameters (yay!).	So we shouldn't be here.
+		 */
+		warn("More than 10 words (%d) of arguments!\n", nargs);
+		break;
+	case 10:
+	case 9:
+	case 8:
+	case 7:
+	case 6:
+	case 5:
+		/*
+		 * If there are 7-10 words of arguments, they are placed
+		 * on the stack, as is normal for other processors.
+		 * The fall-through for all of these is deliberate!!!
+		 */
+		// XXX BAD constant used here
+		iorequest.piod_op = PIOD_READ_D;
+		iorequest.piod_offs = (void *)(regs.r_regs[SP] +
+		    4 * sizeof(uint32_t));
+		iorequest.piod_addr = &fsc->args[4];
+		iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]);
+		ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+		if (iorequest.piod_len == 0)
+			return;
+	case 4:	fsc->args[3] = regs.r_regs[A3];
+	case 3:	fsc->args[2] = regs.r_regs[A2];
+	case 2:	fsc->args[1] = regs.r_regs[A1];
+	case 1:	fsc->args[0] = regs.r_regs[A0];
+	case 0: break;
+	}
+	if (indir) {
+		memmove(&fsc->args[0], &fsc->args[1],
+		    (nargs - 1) * sizeof(fsc->args[0]));
+	}
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -280,66 +293,74 @@
  */
 
 long
-mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
+{
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
-  cpid = trussinfo->curthread->tid;
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "\n");
-    return (-1);
-  }
-  retval = regs.r_regs[V0];
-  errorp = !!regs.r_regs[A3];
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "\n");
+		return (-1);
+	}
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
+	retval = regs.r_regs[V0];
+	errorp = !!regs.r_regs[A3];
+
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-	            retval, fsc.sc);
-  clear_fsc();
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  return (retval);
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
+
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/powerpc-fbsd.c
===================================================================
--- trunk/usr.bin/truss/powerpc-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/powerpc-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -61,11 +61,9 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #ifdef __powerpc64__	/* 32-bit compatibility */
 #include "freebsd32_syscalls.h"
-#define  syscallnames freebsd32_syscallnames
+#define	syscallnames	freebsd32_syscallnames
 #else			/* native 32-bit */
 #include "syscalls.h"
 #endif
@@ -81,7 +79,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -88,22 +86,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -114,148 +118,148 @@
  */
 
 void
-powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  char buf[32];
-  struct reg regs;
-  void *args;
-  int syscall_num;
-  int i;
-  unsigned int regargs;
-  struct syscall *sc;
+powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	void *args;
+	lwpid_t tid;
+	int i, regargs, syscall_num;
 
-  /* Account for a 64-bit argument with corresponding alignment. */
-  nargs += 2;
+	/* Account for a 64-bit argument with corresponding alignment. */
+	nargs += 2;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  regargs = NARGREG;
-  syscall_num = regs.fixreg[0];
-  args = &regs.fixreg[3];
-  if (syscall_num == SYS_syscall) {
-    args = &regs.fixreg[4];
-    regargs -= 1;
-    syscall_num = regs.fixreg[3];
-  } else if (syscall_num == SYS___syscall) {
-    args = &regs.fixreg[5];
-    regargs -= 2;
-    syscall_num = regs.fixreg[4];
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	regargs = NARGREG;
+	syscall_num = regs.fixreg[0];
+	args = &regs.fixreg[3];
+	if (syscall_num == SYS_syscall) {
+		args = &regs.fixreg[4];
+		regargs -= 1;
+		syscall_num = regs.fixreg[3];
+	} else if (syscall_num == SYS___syscall) {
+		args = &regs.fixreg[5];
+		regargs -= 2;
+		syscall_num = regs.fixreg[4];
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
+	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]));
+	if (nargs > regargs) {
+		memmove(&fsc->args[0], args, 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]));
-  }
+		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, tid, (caddr_t)&iorequest, 0);
+		if (iorequest.piod_len == 0)
+			return;
+	} else
+		memmove(&fsc->args[0], args, nargs * sizeof(fsc->args[0]));
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -268,76 +272,80 @@
 long
 powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "\n");
-    return (-1);
-  }
-  retval = regs.fixreg[3];
-  errorp = !!(regs.cr & 0x10000000);
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "\n");
+		return (-1);
+	}
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	retval = regs.fixreg[3];
+	errorp = !!(regs.cr & 0x10000000);
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * On 32-bit big-endian, the low word of a 64-bit return is
-     * in the greater address. Switch to this. XXX note that
-     * print_syscall_ret can't handle 64-bit return values (llseek)
-     */
-    if (sc->ret_type == 2)
-      retval = regs.fixreg[4];
-
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * On 32-bit big-endian, the low word of a 64-bit return is
+		 * in the greater address. Switch to this. XXX note that
+		 * print_syscall_ret can't handle 64-bit return values (llseek)
+		 */
+		if (sc->ret_type == 2)
+			retval = regs.fixreg[4];
 
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
 
-  return (retval);
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/powerpc64-fbsd.c
===================================================================
--- trunk/usr.bin/truss/powerpc64-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/powerpc64-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -61,8 +61,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -76,7 +74,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -83,22 +81,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -109,141 +113,141 @@
  */
 
 void
-powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  char buf[32];
-  struct reg regs;
-  void *args;
-  int syscall_num;
-  int i;
-  unsigned int regargs;
-  struct syscall *sc;
+powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	void *args;
+	lwpid_t tid;
+	int i, regargs, syscall_num;
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  regargs = NARGREG;
-  syscall_num = regs.fixreg[0];
-  args = &regs.fixreg[3];
-  if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
-    args = &regs.fixreg[4];
-    regargs -= 1;
-    syscall_num = regs.fixreg[3];
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	regargs = NARGREG;
+	syscall_num = regs.fixreg[0];
+	args = &regs.fixreg[3];
+	if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
+		args = &regs.fixreg[4];
+		regargs -= 1;
+		syscall_num = regs.fixreg[3];
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
+	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]));
+	if (nargs > regargs) {
+		memmove(&fsc->args[0], args, regargs * sizeof(fsc->args[0]));
 
-    iorequest.piod_op = PIOD_READ_D;
-    iorequest.piod_offs = (void *)(regs.fixreg[1] + 48);
-    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]));
-  }
+		iorequest.piod_op = PIOD_READ_D;
+		iorequest.piod_offs = (void *)(regs.fixreg[1] + 48);
+		iorequest.piod_addr = &fsc->args[regargs];
+		iorequest.piod_len = (nargs - regargs) * sizeof(fsc->args[0]);
+		ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
+		if (iorequest.piod_len == 0)
+			return;
+	} else
+		memmove(&fsc->args[0], args, nargs * sizeof(fsc->args[0]));
 
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -256,68 +260,72 @@
 long
 powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
 {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "\n");
-    return (-1);
-  }
-  retval = regs.fixreg[3];
-  errorp = !!(regs.cr & 0x10000000);
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "\n");
+		return (-1);
+	}
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	retval = regs.fixreg[3];
+	errorp = !!(regs.cr & 0x10000000);
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
 
-  return (retval);
+	return (retval);
 }

Modified: trunk/usr.bin/truss/setup.c
===================================================================
--- trunk/usr.bin/truss/setup.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/setup.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -57,7 +57,7 @@
 #include "truss.h"
 #include "extern.h"
 
-static int child_pid;
+static sig_atomic_t detaching;
 
 /*
  * setup_and_wait() is called to start a process.  All it really does
@@ -69,27 +69,21 @@
 int
 setup_and_wait(char *command[])
 {
-	int pid;
-	int waitval;
+	pid_t pid;
 
 	pid = vfork();
-	if (pid == -1) {
+	if (pid == -1)
 		err(1, "fork failed");
-	}
 	if (pid == 0) {	/* Child */
 		ptrace(PT_TRACE_ME, 0, 0, 0);
 		execvp(command[0], command);
 		err(1, "execvp %s", command[0]);
 	}
-	
+
 	/* Only in the parent here */
-	if (waitpid(pid, &waitval, 0) < 0) {
+	if (waitpid(pid, NULL, 0) < 0)
 		err(1, "unexpect stop in waitpid");
-		return 0;
-	}
 
-	child_pid = pid;
-	
 	return (pid);
 }
 
@@ -100,21 +94,19 @@
  */
 
 int
-start_tracing(int pid)
+start_tracing(pid_t pid)
 {
-	int waitval;
-	int ret;
-	int retry = 10;
+	int ret, retry;
 
+	retry = 10;
 	do {
 		ret = ptrace(PT_ATTACH, pid, NULL, 0);
 		usleep(200);
-	} while(ret && retry-- > 0);
+	} while (ret && retry-- > 0);
 	if (ret)
 		err(1, "can not attach to target process");
 
-	child_pid = pid;	
-	if (waitpid(pid, &waitval, 0) < 0) 
+	if (waitpid(pid, NULL, 0) < 0)
 		err(1, "Unexpect stop in waitpid");
 
 	return (0);
@@ -126,21 +118,30 @@
  * applies if truss was told to monitor an already-existing
  * process.
  */
+
 void
 restore_proc(int signo __unused)
 {
+
+	detaching = 1;
+}
+
+static int
+detach_proc(pid_t pid)
+{
 	int waitval;
 
-	/* stop the child so that we can detach */	
-	kill(child_pid, SIGSTOP);
-	if (waitpid(child_pid, &waitval, 0) < 0)
+	/* stop the child so that we can detach */
+	kill(pid, SIGSTOP);
+	if (waitpid(pid, &waitval, 0) < 0)
 		err(1, "Unexpected stop in waitpid");
 
-	if (ptrace(PT_DETACH, child_pid, (caddr_t)1, 0) < 0)
+	if (ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0)
 		err(1, "Can not detach the process");
-	
-	kill(child_pid, SIGCONT);
-	exit(0);
+
+	kill(pid, SIGCONT);
+
+	return (waitval);
 }
 
 /*
@@ -150,21 +151,20 @@
 static void
 find_thread(struct trussinfo *info, lwpid_t lwpid)
 {
+	struct threadinfo *np;
+
 	info->curthread = NULL;
-	struct threadinfo *np;
 	SLIST_FOREACH(np, &info->threadlist, entries) {
-	if (np->tid == lwpid) {
-		info->curthread = np;
-		return;
+		if (np->tid == lwpid) {
+			info->curthread = np;
+			return;
 		}
 	}
 
-	np = (struct threadinfo *)malloc(sizeof(struct threadinfo));
+	np = (struct threadinfo *)calloc(1, sizeof(struct threadinfo));
 	if (np == NULL)
-		errx(1, "malloc() failed");
+		err(1, "calloc() failed");
 	np->tid = lwpid;
-	np->in_fork = 0;
-	np->in_syscall = 0;
 	SLIST_INSERT_HEAD(&info->threadlist, np, entries);
 	info->curthread = np;
 }
@@ -177,16 +177,27 @@
 void
 waitevent(struct trussinfo *info)
 {
+	struct ptrace_lwpinfo lwpinfo;
+	static int pending_signal = 0;
 	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) < 0) {
+detach:
+	if (detaching) {
+		waitval = detach_proc(info->pid);
+		info->pr_why = S_DETACHED;
+		info->pr_data = WEXITSTATUS(waitval);
+		return;
+	}
+
+	if (waitpid(info->pid, &waitval, 0) == -1) {
+		if (errno == EINTR)
+			goto detach;
 		err(1, "Unexpected stop in waitpid");
 	}
-	
+
 	if (WIFCONTINUED(waitval)) {
 		info->pr_why = S_NONE;
 		return;
@@ -197,10 +208,10 @@
 		return;
 	}
 	if (WIFSTOPPED(waitval)) {
-		struct ptrace_lwpinfo lwpinfo;
-		ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo));	
+		ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo,
+		    sizeof(lwpinfo));
 		find_thread(info, lwpinfo.pl_lwpid);
-		switch(WSTOPSIG(waitval)) {
+		switch (WSTOPSIG(waitval)) {
 		case SIGTRAP:
 			if (lwpinfo.pl_flags & PL_FLAG_SCE) {
 				info->pr_why = S_SCE;

Modified: trunk/usr.bin/truss/sparc64-fbsd.c
===================================================================
--- trunk/usr.bin/truss/sparc64-fbsd.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/sparc64-fbsd.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -67,8 +67,6 @@
 #include "syscall.h"
 #include "extern.h"
 
-static int cpid = -1;
-
 #include "syscalls.h"
 
 static int nsyscalls = sizeof(syscallnames) / sizeof(syscallnames[0]);
@@ -82,7 +80,7 @@
  * 'struct syscall' describes the system call; it may be NULL, however,
  * if we don't know about this particular system call yet.
  */
-static struct freebsd_syscall {
+struct freebsd_syscall {
 	struct syscall *sc;
 	const char *name;
 	int number;
@@ -89,22 +87,28 @@
 	unsigned long *args;
 	int nargs;	/* number of arguments -- *not* number of words! */
 	char **s_args;	/* the printable arguments */
-} fsc;
+};
 
+static struct freebsd_syscall *
+alloc_fsc(void)
+{
+
+	return (malloc(sizeof(struct freebsd_syscall)));
+}
+
 /* Clear up and free parts of the fsc structure. */
-static __inline void
-clear_fsc(void) {
-  if (fsc.args) {
-    free(fsc.args);
-  }
-  if (fsc.s_args) {
-    int i;
-    for (i = 0; i < fsc.nargs; i++)
-      if (fsc.s_args[i])
-	free(fsc.s_args[i]);
-    free(fsc.s_args);
-  }
-  memset(&fsc, 0, sizeof(fsc));
+static void
+free_fsc(struct freebsd_syscall *fsc)
+{
+	int i;
+
+	free(fsc->args);
+	if (fsc->s_args) {
+		for (i = 0; i < fsc->nargs; i++)
+			free(fsc->s_args[i]);
+		free(fsc->s_args);
+	}
+	free(fsc);
 }
 
 /*
@@ -115,159 +119,164 @@
  */
 
 void
-sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
-  struct reg regs;
-  int syscall_num;
-  int i;
-  struct syscall *sc;
-  int indir = 0;	/* indirect system call */
-  struct ptrace_io_desc iorequest;
+sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs)
+{
+	struct ptrace_io_desc iorequest;
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	int i, syscall_num;
+	int indir;	/* indirect system call */
 
-  cpid = trussinfo->curthread->tid;
+	tid = trussinfo->curthread->tid;
 
-  clear_fsc();
-  
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
-    return;
-  }
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
+		return;
+	}
 
-  /*
-   * FreeBSD has two special kinds of system call redirctions --
-   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
-   * routine, basically; the latter is for quad-aligned arguments.
-   */
-  syscall_num = regs.r_global[1];
-  if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
-    indir = 1;
-    syscall_num = regs.r_out[0];
-  }
+	/*
+	 * FreeBSD has two special kinds of system call redirctions --
+	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
+	 * routine, basically; the latter is for quad-aligned arguments.
+	 */
+	indir = 0;
+	syscall_num = regs.r_global[1];
+	if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
+		indir = 1;
+		syscall_num = regs.r_out[0];
+	}
 
-  fsc.number = syscall_num;
-  fsc.name =
-    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
-  if (!fsc.name) {
-    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
-  }
+	fsc = alloc_fsc();
+	if (fsc == NULL)
+		return;
+	fsc->number = syscall_num;
+	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
+	    NULL : syscallnames[syscall_num];
+	if (!fsc->name) {
+		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
+		    syscall_num);
+	}
 
-  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
-   && ((!strcmp(fsc.name, "fork")
-    || !strcmp(fsc.name, "rfork")
-    || !strcmp(fsc.name, "vfork"))))
-  {
-    trussinfo->curthread->in_fork = 1;
-  }
+	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
+	    (strcmp(fsc->name, "fork") == 0 ||
+	    strcmp(fsc->name, "rfork") == 0 ||
+	    strcmp(fsc->name, "vfork") == 0))
+		trussinfo->curthread->in_fork = 1;
 
-  if (nargs == 0)
-    return;
+	if (nargs == 0)
+		return;
 
-  fsc.args = malloc((1+nargs) * sizeof(unsigned long));
-  switch (nargs) {
-  default:
-	/*
-	 * The OS doesn't seem to allow more than 10 words of
-	 * parameters (yay!).  So we shouldn't be here.
-	 */
-	warn("More than 10 words (%d) of arguments!\n", nargs);
-	break;
-  case 10: case 9: case 8: case 7:
-	/*
-	 * If there are 7-10 words of arguments, they are placed
-	 * on the stack, as is normal for other processors.
-	 * The fall-through for all of these is deliberate!!!
-	 */
-	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;
+	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
+	switch (nargs) {
+	default:
+		/*
+		 * The OS doesn't seem to allow more than 10 words of
+		 * parameters (yay!).	So we shouldn't be here.
+		 */
+		warn("More than 10 words (%d) of arguments!\n", nargs);
+		break;
+	case 10:
+	case 9:
+	case 8:
+	case 7:
+		/*
+		 * If there are 7-10 words of arguments, they are placed
+		 * on the stack, as is normal for other processors.
+		 * The fall-through for all of these is deliberate!!!
+		 */
+		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, tid, (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];
+	case 3:	fsc->args[2] = regs.r_out[2];
+	case 2:	fsc->args[1] = regs.r_out[1];
+	case 1:	fsc->args[0] = regs.r_out[0];
+	case 0:
+		break;
+	}
 
-  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];
-  case 3:	fsc.args[2] = regs.r_out[2];
-  case 2:	fsc.args[1] = regs.r_out[1];
-  case 1:	fsc.args[0] = regs.r_out[0];
-  case 0:
-	break;
-  }
+	if (indir)
+		memmove(&fsc->args[0], &fsc->args[1], (nargs - 1) *
+		    sizeof(fsc->args[0]));
 
-  if (indir) {
-    memmove(&fsc.args[0], &fsc.args[1], (nargs-1) * sizeof(fsc.args[0]));
-  }
-
-  sc = get_syscall(fsc.name);
-  if (sc) {
-    fsc.nargs = sc->nargs;
-  } else {
+	sc = get_syscall(fsc->name);
+	if (sc)
+		fsc->nargs = sc->nargs;
+	else {
 #if DEBUG
-    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
-	   fsc.name, nargs);
+		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
+		    "args to %d\n", fsc->name, nargs);
 #endif
-    fsc.nargs = nargs;
-  }
+		fsc->nargs = nargs;
+	}
 
-  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
-  fsc.sc = sc;
+	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
+	fsc->sc = sc;
 
-  /*
-   * At this point, we set up the system call arguments.
-   * We ignore any OUT ones, however -- those are arguments that
-   * are set by the system call, and so are probably meaningless
-   * now.  This doesn't currently support arguments that are
-   * passed in *and* out, however.
-   */
+	/*
+	 * At this point, we set up the system call arguments.
+	 * We ignore any OUT ones, however -- those are arguments that
+	 * are set by the system call, and so are probably meaningless
+	 * now.	This doesn't currently support arguments that are
+	 * passed in *and* out, however.
+	 */
 
-  if (fsc.name) {
-
+	if (fsc->name) {
 #if DEBUG
-    fprintf(stderr, "syscall %s(", fsc.name);
+		fprintf(stderr, "syscall %s(", fsc->name);
 #endif
-    for (i = 0; i < fsc.nargs; i++) {
+		for (i = 0; i < fsc->nargs; i++) {
 #if DEBUG
-      fprintf(stderr, "0x%x%s",
-	      sc
-	      ? fsc.args[sc->args[i].offset]
-	      : fsc.args[i],
-	      i < (fsc.nargs - 1) ? "," : "");
+			fprintf(stderr, "0x%x%s", sc ?
+			    fsc->args[sc->args[i].offset] : fsc->args[i],
+			    i < (fsc->nargs - 1) ? "," : "");
 #endif
-      if (sc && !(sc->args[i].type & OUT)) {
-	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
-      }
-    }
+			if (sc && !(sc->args[i].type & OUT)) {
+				fsc->s_args[i] = print_arg(&sc->args[i],
+				    fsc->args, 0, trussinfo);
+			}
+		}
 #if DEBUG
-    fprintf(stderr, ")\n");
+		fprintf(stderr, ")\n");
 #endif
-  }
+	}
 
 #if DEBUG
-  fprintf(trussinfo->outfile, "\n");
+	fprintf(trussinfo->outfile, "\n");
 #endif
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-
-    /* XXX
-     * This could be done in a more general
-     * manner but it still wouldn't be very pretty.
-     */
-    if (!strcmp(fsc.name, "execve")) {
-        if ((trussinfo->flags & EXECVEARGS) == 0)
-          if (fsc.s_args[1]) {
-            free(fsc.s_args[1]);
-            fsc.s_args[1] = NULL;
-          }
-        if ((trussinfo->flags & EXECVEENVS) == 0)
-          if (fsc.s_args[2]) {
-            free(fsc.s_args[2]);
-            fsc.s_args[2] = NULL;
-          }
-    }
-  }
-
-  return;
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0)) {
+		/*
+		 * XXX
+		 * This could be done in a more general
+		 * manner but it still wouldn't be very pretty.
+		 */
+		if (strcmp(fsc->name, "execve") == 0) {
+			if ((trussinfo->flags & EXECVEARGS) == 0) {
+				if (fsc->s_args[1]) {
+					free(fsc->s_args[1]);
+					fsc->s_args[1] = NULL;
+				}
+			}
+			if ((trussinfo->flags & EXECVEENVS) == 0) {
+				if (fsc->s_args[2]) {
+					free(fsc->s_args[2]);
+					fsc->s_args[2] = NULL;
+				}
+			}
+		}
+	}
+	trussinfo->curthread->fsc = fsc;
 }
 
 /*
@@ -278,66 +287,74 @@
  */
 
 long
-sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) {
-  struct reg regs;
-  long retval;
-  int i;
-  int errorp;
-  struct syscall *sc;
+sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
+{
+	struct reg regs;
+	struct freebsd_syscall *fsc;
+	struct syscall *sc;
+	lwpid_t tid;
+	long retval;
+	int errorp, i;
 
-  if (fsc.name == NULL)
-	return (-1);
-  cpid = trussinfo->curthread->tid;
+	if (trussinfo->curthread->fsc == NULL)
+		return (-1);
 
-  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
-    fprintf(trussinfo->outfile, "\n");
-    return (-1);
-  }
-  retval = regs.r_out[0];
-  errorp = !!(regs.r_tstate & TSTATE_XCC_C);
+	tid = trussinfo->curthread->tid;
 
-  /*
-   * This code, while simpler than the initial versions I used, could
-   * stand some significant cleaning.
-   */
+	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
+		fprintf(trussinfo->outfile, "\n");
+		return (-1);
+	}
 
-  sc = fsc.sc;
-  if (!sc) {
-    for (i = 0; i < fsc.nargs; i++)
-      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
-  } else {
-    /*
-     * Here, we only look for arguments that have OUT masked in --
-     * otherwise, they were handled in the syscall_entry function.
-     */
-    for (i = 0; i < sc->nargs; i++) {
-      char *temp;
-      if (sc->args[i].type & OUT) {
+	retval = regs.r_out[0];
+	errorp = !!(regs.r_tstate & TSTATE_XCC_C);
+
 	/*
-	 * If an error occurred, than don't bothe getting the data;
-	 * it may not be valid.
+	 * This code, while simpler than the initial versions I used, could
+	 * stand some significant cleaning.
 	 */
-	if (errorp)
-	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
-	else
-	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
-	fsc.s_args[i] = temp;
-      }
-    }
-  }
 
-  if (fsc.name != NULL &&
-      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
-	trussinfo->curthread->in_syscall = 1;
-  }
-  /*
-   * It would probably be a good idea to merge the error handling,
-   * but that complicates things considerably.
-   */
+	fsc = trussinfo->curthread->fsc;
+	sc = fsc->sc;
+	if (!sc) {
+		for (i = 0; i < fsc->nargs; i++)
+			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
+	} else {
+		/*
+		 * Here, we only look for arguments that have OUT masked in --
+		 * otherwise, they were handled in the syscall_entry function.
+		 */
+		for (i = 0; i < sc->nargs; i++) {
+			char *temp;
+			if (sc->args[i].type & OUT) {
+				/*
+				 * If an error occurred, then don't bother
+				 * getting the data; it may not be valid.
+				 */
+				if (errorp) {
+					asprintf(&temp, "0x%lx",
+					    fsc->args[sc->args[i].offset]);
+				} else {
+					temp = print_arg(&sc->args[i],
+					    fsc->args, retval, trussinfo);
+				}
+				fsc->s_args[i] = temp;
+			}
+		}
+	}
 
-  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
-		    retval, fsc.sc);
-  clear_fsc();
+	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
+	    strcmp(fsc->name, "exit") == 0))
+		trussinfo->curthread->in_syscall = 1;
 
-  return (retval);
+	/*
+	 * It would probably be a good idea to merge the error handling,
+	 * but that complicates things considerably.
+	 */
+
+	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
+	    retval, fsc->sc);
+	free_fsc(fsc);
+
+	return (retval);
 }

Modified: trunk/usr.bin/truss/syscall.h
===================================================================
--- trunk/usr.bin/truss/syscall.h	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/syscall.h	2016-09-16 22:14:07 UTC (rev 8144)
@@ -42,9 +42,9 @@
 	Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
 	Pathconf };
 
-#define ARG_MASK	0xff
-#define OUT	0x100
-#define IN	/*0x20*/0
+#define	ARG_MASK	0xff
+#define	OUT	0x100
+#define	IN	/*0x20*/0
 
 struct syscall_args {
 	enum Argtype type;

Modified: trunk/usr.bin/truss/syscalls.c
===================================================================
--- trunk/usr.bin/truss/syscalls.c	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/syscalls.c	2016-09-16 22:14:07 UTC (rev 8144)
@@ -269,8 +269,8 @@
 	const char *str;
 };
 
-#define X(a) { a, #a },
-#define XEND { 0, NULL }
+#define	X(a)	{ a, #a },
+#define	XEND	{ 0, NULL }
 
 static struct xlat kevent_filters[] = {
 	X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE)
@@ -414,10 +414,11 @@
 static char *
 xlookup_bits(struct xlat *xlat, int val)
 {
+	int len, rem;
 	static char str[512];
-	int len = 0;
-	int rem = val;
 
+	len = 0;
+	rem = val;
 	for (; xlat->str != NULL; xlat++) {
 		if ((xlat->val & rem) == xlat->val) {
 			/* don't print the "all-bits-zero" string unless all
@@ -445,12 +446,13 @@
 struct syscall *
 get_syscall(const char *name)
 {
-	struct syscall *sc = syscalls;
+	struct syscall *sc;
 
+	sc = syscalls;
 	if (name == NULL)
 		return (NULL);
 	while (sc->name) {
-		if (!strcmp(name, sc->name))
+		if (strcmp(name, sc->name) == 0)
 			return (sc);
 		sc++;
 	}
@@ -464,7 +466,7 @@
  */
 
 static int
-get_struct(int pid, void *offset, void *buf, int len)
+get_struct(pid_t pid, void *offset, void *buf, int len)
 {
 	struct ptrace_io_desc iorequest;
 
@@ -477,8 +479,8 @@
 	return (0);
 }
 
-#define MAXSIZE 4096
-#define BLOCKSIZE 1024
+#define	MAXSIZE		4096
+#define	BLOCKSIZE	1024
 /*
  * get_string
  * Copy a string from the process.  Note that it is
@@ -489,12 +491,11 @@
 static char *
 get_string(pid_t pid, void *offset, int max)
 {
+	struct ptrace_io_desc iorequest;
 	char *buf;
-	struct ptrace_io_desc iorequest;
-	int totalsize, size;
-	int diff = 0;
-	int i;
+	int diff, i, size, totalsize;
 
+	diff = 0;
 	totalsize = size = max ? (max + 1) : BLOCKSIZE;
 	buf = malloc(totalsize);
 	if (buf == NULL)
@@ -536,11 +537,14 @@
  */
 
 char *
-print_arg(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;
+	char *tmp;
+	pid_t pid;
 
+	tmp = NULL;
+	pid = trussinfo->pid;
 	switch (sc->type & ARG_MASK) {
 	case Hex:
 		asprintf(&tmp, "0x%x", (int)args[sc->offset]);
@@ -581,15 +585,18 @@
 			len = max_string;
 			truncated = 1;
 		}
-		if (len && get_struct(pid, (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)
+				if (strvisx(tmp3, tmp2, len,
+				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
 					break;
 				len--;
 				truncated = 1;
 			};
-			asprintf(&tmp, "\"%s\"%s", tmp3, truncated?"...":"");
+			asprintf(&tmp, "\"%s\"%s", tmp3, truncated ?
+			    "..." : "");
 			free(tmp3);
 		} else {
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
@@ -602,10 +609,9 @@
 		char *string;
 		char *strarray[100];	/* XXX This is ugly. */
 
-		if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray,
-			sizeof(strarray)) == -1) {
+		if (get_struct(pid, (void *)args[sc->offset],
+		    (void *)&strarray, sizeof(strarray)) == -1)
 			err(1, "get_struct %p", (void *)args[sc->offset]);
-		}
 		num = 0;
 		size = 0;
 
@@ -623,7 +629,8 @@
 		tmp2 += sprintf(tmp2, " [");
 		for (i = 0; i < num; i++) {
 			string = get_string(pid, (void*)strarray[i], 0);
-			tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i+1 == num) ? ' ' : ',');
+			tmp2 += sprintf(tmp2, " \"%s\"%c", string,
+			    (i + 1 == num) ? ' ' : ',');
 			free(string);
 		}
 		tmp2 += sprintf(tmp2, "]");
@@ -657,13 +664,14 @@
 	}
 	case Ioctl: {
 		const char *temp = ioctlname(args[sc->offset]);
-		if (temp) {
+		if (temp)
 			tmp = strdup(temp);
-		} else {
+		else {
 			unsigned long arg = args[sc->offset];
-			asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", arg,
-			    arg&IOC_OUT?"R":"", arg&IOC_IN?"W":"",
-			    IOCGROUP(arg), isprint(IOCGROUP(arg))?(char)IOCGROUP(arg):'?',
+			asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
+			    arg, arg & IOC_OUT ? "R" : "",
+			    arg & IOC_IN ? "W" : "", IOCGROUP(arg),
+			    isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?',
 			    arg & 0xFF, IOCPARM_LEN(arg));
 		}
 		break;
@@ -670,7 +678,8 @@
 	}
 	case Umtx: {
 		struct umtx umtx;
-		if (get_struct(pid, (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]);
@@ -678,8 +687,10 @@
 	}
 	case Timespec: {
 		struct timespec ts;
-		if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1)
-			asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, ts.tv_nsec);
+		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]);
 		break;
@@ -686,8 +697,10 @@
 	}
 	case Timeval: {
 		struct timeval tv;
-		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1)
-			asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, tv.tv_usec);
+		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]);
 		break;
@@ -694,7 +707,8 @@
 	}
 	case Timeval2: {
 		struct timeval tv[2];
-		if (get_struct(pid, (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);
@@ -704,7 +718,8 @@
 	}
 	case Itimerval: {
 		struct itimerval itv;
-		if (get_struct(pid, (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,
@@ -716,8 +731,9 @@
 	}
 	case Pollfd: {
 		/*
-		 * XXX: A Pollfd argument expects the /next/ syscall argument to be
-		 * the number of fds in the array. This matches the poll syscall.
+		 * XXX: A Pollfd argument expects the /next/ syscall argument
+		 * to be the number of fds in the array. This matches the poll
+		 * syscall.
 		 */
 		struct pollfd *pfd;
 		int numfds = args[sc->offset+1];
@@ -726,22 +742,22 @@
 		const int per_fd = 100;
 
 		if ((pfd = malloc(bytes)) == NULL)
-			err(1, "Cannot malloc %d bytes for pollfd array", bytes);
-		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) {
-
+			err(1, "Cannot malloc %d bytes for pollfd array",
+			    bytes);
+		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
+		    != -1) {
 			used = 0;
 			tmpsize = 1 + per_fd * numfds + 2;
 			if ((tmp = malloc(tmpsize)) == NULL)
-				err(1, "Cannot alloc %d bytes for poll output", tmpsize);
+				err(1, "Cannot alloc %d bytes for poll output",
+				    tmpsize);
 
 			tmp[used++] = '{';
 			for (i = 0; i < numfds; i++) {
 
-				u = snprintf(tmp + used, per_fd,
-				    "%s%d/%s",
-				    i > 0 ? " " : "",
-				    pfd[i].fd,
-				    xlookup_bits(poll_flags, pfd[i].events) );
+				u = snprintf(tmp + used, per_fd, "%s%d/%s",
+				    i > 0 ? " " : "", pfd[i].fd,
+				    xlookup_bits(poll_flags, pfd[i].events));
 				if (u > 0)
 					used += u < per_fd ? u : per_fd;
 			}
@@ -755,8 +771,9 @@
 	}
 	case Fd_set: {
 		/*
-		 * XXX: A Fd_set argument expects the /first/ syscall argument to be
-		 * the number of fds in the array.  This matches the select syscall.
+		 * XXX: A Fd_set argument expects the /first/ syscall argument
+		 * to be the number of fds in the array.  This matches the
+		 * select syscall.
 		 */
 		fd_set *fds;
 		int numfds = args[0];
@@ -765,17 +782,21 @@
 		const int per_fd = 20;
 
 		if ((fds = malloc(bytes)) == NULL)
-			err(1, "Cannot malloc %d bytes for fd_set array", bytes);
-		if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) {
+			err(1, "Cannot malloc %d bytes for fd_set array",
+			    bytes);
+		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
+		    != -1) {
 			used = 0;
 			tmpsize = 1 + numfds * per_fd + 2;
 			if ((tmp = malloc(tmpsize)) == NULL)
-				err(1, "Cannot alloc %d bytes for fd_set output", tmpsize);
+				err(1, "Cannot alloc %d bytes for fd_set "
+				    "output", tmpsize);
 
 			tmp[used++] = '{';
 			for (i = 0; i < numfds; i++) {
 				if (FD_ISSET(i, fds)) {
-					u = snprintf(tmp + used, per_fd, "%d ", i);
+					u = snprintf(tmp + used, per_fd, "%d ",
+					    i);
 					if (u > 0)
 						used += u < per_fd ? u : per_fd;
 				}
@@ -784,9 +805,8 @@
 				used--;
 			tmp[used++] = '}';
 			tmp[used++] = '\0';
-		} else {
+		} else
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
-		}
 		free(fds);
 		break;
 	}
@@ -805,7 +825,8 @@
 		int i, used;
 
 		sig = args[sc->offset];
-		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss)) == -1) {
+		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
+		    sizeof(ss)) == -1) {
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
 			break;
 		}
@@ -812,9 +833,8 @@
 		tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
 		used = 0;
 		for (i = 1; i < sys_nsig; i++) {
-			if (sigismember(&ss, i)) {
+			if (sigismember(&ss, i))
 				used += sprintf(tmp + used, "%s|", strsig(i));
-			}
 		}
 		if (used)
 			tmp[used-1] = 0;
@@ -824,7 +844,7 @@
 	}
 	case Sigprocmask: {
 		switch (args[sc->offset]) {
-#define S(a)	case a: tmp = strdup(#a); break;
+#define	S(a)	case a: tmp = strdup(#a); break;
 			S(SIG_BLOCK);
 			S(SIG_UNBLOCK);
 			S(SIG_SETMASK);
@@ -838,10 +858,12 @@
 		/* XXX output depends on the value of the previous argument */
 		switch (args[sc->offset-1]) {
 		case F_SETFD:
-			tmp = strdup(xlookup_bits(fcntlfd_arg, args[sc->offset]));
+			tmp = strdup(xlookup_bits(fcntlfd_arg,
+			    args[sc->offset]));
 			break;
 		case F_SETFL:
-			tmp = strdup(xlookup_bits(fcntlfl_arg, args[sc->offset]));
+			tmp = strdup(xlookup_bits(fcntlfl_arg,
+			    args[sc->offset]));
 			break;
 		case F_GETFD:
 		case F_GETFL:
@@ -902,7 +924,7 @@
 
 		/* yuck: get ss_len */
 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
-			sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
+		    sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
 			err(1, "get_struct %p", (void *)args[sc->offset]);
 		/*
 		 * If ss_len is 0, then try to guess from the sockaddr type.
@@ -922,8 +944,8 @@
 				break;
 			}
 		}
-		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len)
-		    == -1) {
+		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
+		    ss.ss_len) == -1) {
 			err(2, "get_struct %p", (void *)args[sc->offset]);
 		}
 
@@ -931,12 +953,15 @@
 		case AF_INET:
 			lsin = (struct sockaddr_in *)&ss;
 			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr);
-			asprintf(&tmp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port));
+			asprintf(&tmp, "{ AF_INET %s:%d }", addr,
+			    htons(lsin->sin_port));
 			break;
 		case AF_INET6:
 			lsin6 = (struct sockaddr_in6 *)&ss;
-			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof addr);
-			asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port));
+			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
+			    sizeof addr);
+			asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr,
+			    htons(lsin6->sin6_port));
 			break;
 		case AF_UNIX:
 			sun = (struct sockaddr_un *)&ss;
@@ -944,12 +969,14 @@
 			break;
 		default:
 			sa = (struct sockaddr *)&ss;
-			asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data = {%n%*s } }",
-			    (int)sa->sa_len, (int)sa->sa_family, &i,
-			    6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), "");
+			asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data "
+			    "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family,
+			    &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data -
+			    (char *)sa)), "");
 			if (tmp != NULL) {
 				p = tmp + i;
-				for (q = (u_char *)&sa->sa_data; q < (u_char *)sa + sa->sa_len; q++)
+				for (q = (u_char *)&sa->sa_data;
+				    q < (u_char *)sa + sa->sa_len; q++)
 					p += sprintf(p, " %#02x,", *q);
 			}
 		}
@@ -960,8 +987,8 @@
 		char *hand;
 		const char *h;
 
-		if (get_struct(pid, (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)
 				h = "SIG_DFL";
@@ -970,13 +997,11 @@
 			else
 				h = hand;
 
-			asprintf(&tmp, "{ %s %s ss_t }",
-			    h,
+			asprintf(&tmp, "{ %s %s ss_t }", h,
 			    xlookup_bits(sigaction_flags, sa.sa_flags));
 			free(hand);
-		} else {
+		} else
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
-		}
 		break;
 	}
 	case Kevent: {
@@ -1001,12 +1026,15 @@
 		if (numevents >= 0)
 			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(pid, (void *)args[sc->offset], ke, bytes) != -1) {
+			err(1, "Cannot malloc %d bytes for kevent array",
+			    bytes);
+		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)
-				err(1, "Cannot alloc %d bytes for kevent output", tmpsize);
+				err(1, "Cannot alloc %d bytes for kevent "
+				    "output", tmpsize);
 
 			tmp[used++] = '{';
 			for (i = 0; i < numevents; i++) {
@@ -1032,12 +1060,14 @@
 	}
 	case Stat: {
 		struct stat st;
-		if (get_struct(pid, (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 }",
-			    mode,
-			    (intmax_t)st.st_ino,(intmax_t)st.st_size,(long)st.st_blksize);
+			asprintf(&tmp,
+			    "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", mode,
+			    (intmax_t)st.st_ino, (intmax_t)st.st_size,
+			    (long)st.st_blksize);
 		} else {
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
 		}
@@ -1045,24 +1075,25 @@
 	}
 	case Rusage: {
 		struct rusage ru;
-		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) {
-			asprintf(&tmp, "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }",
+		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,
 			    ru.ru_inblock, ru.ru_oublock);
-		} else {
+		} else
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
-		}
 		break;
 	}
 	case Rlimit: {
 		struct rlimit rl;
-		if (get_struct(pid, (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 {
+		} else
 			asprintf(&tmp, "0x%lx", args[sc->offset]);
-		}
 		break;
 	}
 	default:
@@ -1079,27 +1110,31 @@
  */
 
 void
-print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args)
+print_syscall(struct trussinfo *trussinfo, const char *name, int nargs,
+    char **s_args)
 {
-	int i;
-	int len = 0;
 	struct timespec timediff;
+	int i, len;
 
+	len = 0;
 	if (trussinfo->flags & FOLLOWFORKS)
 		len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid);
 
-	if (name != NULL && (!strcmp(name, "execve") || !strcmp(name, "exit"))) {
-		clock_gettime(CLOCK_REALTIME, &trussinfo->after);
+	if (name != NULL && (strcmp(name, "execve") == 0 ||
+	    strcmp(name, "exit") == 0)) {
+		clock_gettime(CLOCK_REALTIME, &trussinfo->curthread->after);
 	}
 
 	if (trussinfo->flags & ABSOLUTETIMESTAMPS) {
-		timespecsubt(&trussinfo->after, &trussinfo->start_time, &timediff);
+		timespecsubt(&trussinfo->curthread->after,
+		    &trussinfo->start_time, &timediff);
 		len += fprintf(trussinfo->outfile, "%ld.%09ld ",
 		    (long)timediff.tv_sec, timediff.tv_nsec);
 	}
 
 	if (trussinfo->flags & RELATIVETIMESTAMPS) {
-		timespecsubt(&trussinfo->after, &trussinfo->before, &timediff);
+		timespecsubt(&trussinfo->curthread->after,
+		    &trussinfo->curthread->before, &timediff);
 		len += fprintf(trussinfo->outfile, "%ld.%09ld ",
 		    (long)timediff.tv_sec, timediff.tv_nsec);
 	}
@@ -1110,8 +1145,10 @@
 		if (s_args[i])
 			len += fprintf(trussinfo->outfile, "%s", s_args[i]);
 		else
-			len += fprintf(trussinfo->outfile, "<missing argument>");
-		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? "," : "");
+			len += fprintf(trussinfo->outfile,
+			    "<missing argument>");
+		len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ?
+		    "," : "");
 	}
 	len += fprintf(trussinfo->outfile, ")");
 	for (i = 0; i < 6 - (len / 8); i++)
@@ -1127,8 +1164,9 @@
 	if (trussinfo->flags & COUNTONLY) {
 		if (!sc)
 			return;
-		clock_gettime(CLOCK_REALTIME, &trussinfo->after);
-		timespecsubt(&trussinfo->after, &trussinfo->before, &timediff);
+		clock_gettime(CLOCK_REALTIME, &trussinfo->curthread->after);
+		timespecsubt(&trussinfo->curthread->after,
+		    &trussinfo->curthread->before, &timediff);
 		timespecadd(&sc->time, &timediff, &sc->time);
 		sc->ncalls++;
 		if (errorp)
@@ -1138,14 +1176,15 @@
 
 	print_syscall(trussinfo, name, nargs, s_args);
 	fflush(trussinfo->outfile);
-	if (errorp) {
-		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, strerror(retval));
-	} else {
+	if (errorp)
+		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval,
+		    strerror(retval));
+	else {
 		/*
 		 * Because pipe(2) has a special assembly glue to provide the
 		 * libc API, we have to adjust retval.
 		 */
-		if (name != NULL && !strcmp(name, "pipe"))
+		if (name != NULL && strcmp(name, "pipe") == 0)
 			retval = 0;
 		fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval);
 	}
@@ -1154,12 +1193,12 @@
 void
 print_summary(struct trussinfo *trussinfo)
 {
+	struct timespec total = {0, 0};
 	struct syscall *sc;
-	struct timespec total = {0, 0};
 	int ncall, nerror;
 
 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
-		"syscall", "seconds", "calls", "errors");
+	    "syscall", "seconds", "calls", "errors");
 	ncall = nerror = 0;
 	for (sc = syscalls; sc->name != NULL; sc++)
 		if (sc->ncalls) {
@@ -1171,7 +1210,7 @@
 			nerror += sc->nerror;
 		}
 	fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n",
-		"", "-------------", "-------", "-------");
+	    "", "-------------", "-------", "-------");
 	fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
-		"", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
+	    "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror);
 }

Modified: trunk/usr.bin/truss/truss.h
===================================================================
--- trunk/usr.bin/truss/truss.h	2016-09-16 22:12:44 UTC (rev 8143)
+++ trunk/usr.bin/truss/truss.h	2016-09-16 22:14:07 UTC (rev 8144)
@@ -27,13 +27,13 @@
 
 #include <sys/queue.h>
 
-#define FOLLOWFORKS        0x00000001
-#define RELATIVETIMESTAMPS 0x00000002
-#define ABSOLUTETIMESTAMPS 0x00000004
-#define NOSIGS             0x00000008
-#define EXECVEARGS         0x00000010
-#define EXECVEENVS         0x00000020
-#define COUNTONLY          0x00000040
+#define	FOLLOWFORKS		0x00000001
+#define	RELATIVETIMESTAMPS	0x00000002
+#define	ABSOLUTETIMESTAMPS	0x00000004
+#define	NOSIGS			0x00000008
+#define	EXECVEARGS		0x00000010
+#define	EXECVEENVS		0x00000020
+#define	COUNTONLY		0x00000040
 
 struct threadinfo
 {
@@ -41,11 +41,14 @@
 	lwpid_t tid;
 	int in_syscall;
 	int in_fork;
+	void *fsc;
+	struct timespec before;
+	struct timespec after;
 };
 
 struct trussinfo
 {
-	int pid;
+	pid_t pid;
 	int flags;
 	int pr_why;
 	int pr_data;
@@ -53,15 +56,13 @@
 	FILE *outfile;
 
 	struct timespec start_time;
-	struct timespec before;
-	struct timespec after;
 
 	struct threadinfo *curthread;
-	
+
 	SLIST_HEAD(, threadinfo) threadlist;
 };
 
-#define timespecsubt(tvp, uvp, vvp)					\
+#define	timespecsubt(tvp, uvp, vvp)					\
 	do {								\
 		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
 		(vvp)->tv_nsec = (tvp)->tv_nsec - (uvp)->tv_nsec;	\
@@ -71,7 +72,7 @@
 		}							\
 	} while (0)
 
-#define timespecadd(tvp, uvp, vvp)					\
+#define	timespecadd(tvp, uvp, vvp)					\
 	do {								\
 		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
 		(vvp)->tv_nsec = (tvp)->tv_nsec + (uvp)->tv_nsec;	\
@@ -81,9 +82,10 @@
 		}							\
 	} 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
+#define	S_NONE	0
+#define	S_SCE	1
+#define	S_SCX	2
+#define	S_EXIT	3
+#define	S_SIG	4
+#define	S_EXEC	5
+#define	S_DETACHED	6



More information about the Midnightbsd-cvs mailing list