Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2015 18:08:36 +0000 (UTC)
From:      Bryan Drewery <bdrewery@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r288832 - head/usr.bin/truss
Message-ID:  <201510051808.t95I8a0n035052@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bdrewery
Date: Mon Oct  5 18:08:35 2015
New Revision: 288832
URL: https://svnweb.freebsd.org/changeset/base/288832

Log:
  Fix tracking of unknown syscalls for 'truss -c'.
  
  This is done by changing get_syscall() to either lookup the known syscall
  or add it into the list with the default handlers for printing.
  
  This also simplifies some code to not have to check if the syscall variable
  is set or NULL.
  
  Reviewed by:	jhb
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D3792

Modified:
  head/usr.bin/truss/main.c
  head/usr.bin/truss/setup.c
  head/usr.bin/truss/syscall.h
  head/usr.bin/truss/syscalls.c

Modified: head/usr.bin/truss/main.c
==============================================================================
--- head/usr.bin/truss/main.c	Mon Oct  5 17:54:54 2015	(r288831)
+++ head/usr.bin/truss/main.c	Mon Oct  5 18:08:35 2015	(r288832)
@@ -94,6 +94,7 @@ main(int ac, char **av)
 	trussinfo->strsize = 32;
 	trussinfo->curthread = NULL;
 	LIST_INIT(&trussinfo->proclist);
+	init_syscalls();
 	while ((c = getopt(ac, av, "p:o:facedDs:S")) != -1) {
 		switch (c) {
 		case 'p':	/* specified pid */

Modified: head/usr.bin/truss/setup.c
==============================================================================
--- head/usr.bin/truss/setup.c	Mon Oct  5 17:54:54 2015	(r288831)
+++ head/usr.bin/truss/setup.c	Mon Oct  5 18:08:35 2015	(r288832)
@@ -341,17 +341,9 @@ enter_syscall(struct trussinfo *info, st
 		fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n",
 		    t->proc->abi->type, t->cs.number);
 
-	sc = get_syscall(t->cs.name);
-	if (sc) {
-		t->cs.nargs = sc->nargs;
-		assert(sc->nargs <= nitems(t->cs.s_args));
-	} else {
-#if DEBUG
-		fprintf(stderr, "unknown syscall %s -- setting "
-		    "args to %d\n", t->cs.name, t->cs.nargs);
-#endif
-		t->cs.nargs = narg;
-	}
+	sc = get_syscall(t->cs.name, narg);
+	t->cs.nargs = sc->nargs;
+	assert(sc->nargs <= nitems(t->cs.s_args));
 
 	t->cs.sc = sc;
 
@@ -372,7 +364,7 @@ enter_syscall(struct trussinfo *info, st
 			    t->cs.args[sc->args[i].offset] : t->cs.args[i],
 			    i < (t->cs.nargs - 1) ? "," : "");
 #endif
-			if (sc && !(sc->args[i].type & OUT)) {
+			if (!(sc->args[i].type & OUT)) {
 				t->cs.s_args[i] = print_arg(&sc->args[i],
 				    t->cs.args, 0, info);
 			}
@@ -407,31 +399,26 @@ exit_syscall(struct trussinfo *info, str
 	}
 
 	sc = t->cs.sc;
-	if (sc == NULL) {
-		for (i = 0; i < t->cs.nargs; i++)
-			asprintf(&t->cs.s_args[i], "0x%lx", t->cs.args[i]);
-	} else {
-		/*
-		 * Here, we only look for arguments that have OUT masked in --
-		 * otherwise, they were handled in enter_syscall().
-		 */
-		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",
-					    t->cs.args[sc->args[i].offset]);
-				} else {
-					temp = print_arg(&sc->args[i],
-					    t->cs.args, retval, info);
-				}
-				t->cs.s_args[i] = temp;
+	/*
+	 * Here, we only look for arguments that have OUT masked in --
+	 * otherwise, they were handled in enter_syscall().
+	 */
+	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",
+				    t->cs.args[sc->args[i].offset]);
+			} else {
+				temp = print_arg(&sc->args[i],
+				    t->cs.args, retval, info);
 			}
+			t->cs.s_args[i] = temp;
 		}
 	}
 

Modified: head/usr.bin/truss/syscall.h
==============================================================================
--- head/usr.bin/truss/syscall.h	Mon Oct  5 17:54:54 2015	(r288831)
+++ head/usr.bin/truss/syscall.h	Mon Oct  5 18:08:35 2015	(r288832)
@@ -55,6 +55,7 @@ struct syscall_args {
 };
 
 struct syscall {
+	STAILQ_ENTRY(syscall) entries;
 	const char *name;
 	u_int ret_type;	/* 0, 1, or 2 return values */
 	u_int nargs;	/* actual number of meaningful arguments */
@@ -65,7 +66,7 @@ struct syscall {
 	int nerror;	/* Number of calls that returned with error */
 };
 
-struct syscall *get_syscall(const char*);
+struct syscall *get_syscall(const char *, int nargs);
 char *print_arg(struct syscall_args *, unsigned long*, long *, struct trussinfo *);
 
 /*
@@ -108,6 +109,7 @@ struct linux_socketcall_args {
     char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)];
 };
 
+void init_syscalls(void);
 void print_syscall(struct trussinfo *, const char *, int, char **);
 void print_syscall_ret(struct trussinfo *, const char *, int, char **, int,
     long *, struct syscall *);

Modified: head/usr.bin/truss/syscalls.c
==============================================================================
--- head/usr.bin/truss/syscalls.c	Mon Oct  5 17:54:54 2015	(r288831)
+++ head/usr.bin/truss/syscalls.c	Mon Oct  5 18:08:35 2015	(r288832)
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
 /*
  * This should probably be in its own file, sorted alphabetically.
  */
-static struct syscall syscalls[] = {
+static struct syscall decoded_syscalls[] = {
 	{ .name = "fcntl", .ret_type = 1, .nargs = 3,
 	  .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
 	{ .name = "rfork", .ret_type = 1, .nargs = 1,
@@ -370,6 +370,7 @@ static struct syscall syscalls[] = {
 	  .args = { { Ptr, 0 } } },
 	{ .name = 0 },
 };
+static STAILQ_HEAD(, syscall) syscalls;
 
 /* Xlat idea taken from strace */
 struct xlat {
@@ -659,24 +660,49 @@ xlookup_bits(struct xlat *xlat, int val)
 	return (str);
 }
 
+void
+init_syscalls(void)
+{
+	struct syscall *sc;
+
+	STAILQ_INIT(&syscalls);
+	for (sc = decoded_syscalls; sc->name != NULL; sc++)
+		STAILQ_INSERT_HEAD(&syscalls, sc, entries);
+}
 /*
  * If/when the list gets big, it might be desirable to do it
  * as a hash table or binary search.
  */
 struct syscall *
-get_syscall(const char *name)
+get_syscall(const char *name, int nargs)
 {
 	struct syscall *sc;
+	int i;
 
-	sc = syscalls;
 	if (name == NULL)
 		return (NULL);
-	while (sc->name) {
+	STAILQ_FOREACH(sc, &syscalls, entries)
 		if (strcmp(name, sc->name) == 0)
 			return (sc);
-		sc++;
+
+	/* It is unknown.  Add it into the list. */
+#if DEBUG
+	fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
+	    nargs);
+#endif
+
+	sc = calloc(1, sizeof(struct syscall));
+	sc->name = strdup(name);
+	sc->ret_type = 1;
+	sc->nargs = nargs;
+	for (i = 0; i < nargs; i++) {
+		sc->args[i].offset = i;
+		/* Treat all unknown arguments as LongHex. */
+		sc->args[i].type = LongHex;
 	}
-	return (NULL);
+	STAILQ_INSERT_HEAD(&syscalls, sc, entries);
+
+	return (sc);
 }
 
 /*
@@ -1632,8 +1658,6 @@ print_syscall_ret(struct trussinfo *trus
 	struct timespec timediff;
 
 	if (trussinfo->flags & COUNTONLY) {
-		if (!sc)
-			return;
 		clock_gettime(CLOCK_REALTIME, &trussinfo->curthread->after);
 		timespecsubt(&trussinfo->curthread->after,
 		    &trussinfo->curthread->before, &timediff);
@@ -1650,7 +1674,7 @@ print_syscall_ret(struct trussinfo *trus
 		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
 		    strerror(retval[0]));
 #ifndef __LP64__
-	else if (sc != NULL && sc->ret_type == 2) {
+	else if (sc->ret_type == 2) {
 		off_t off;
 
 #if _BYTE_ORDER == _LITTLE_ENDIAN
@@ -1677,7 +1701,7 @@ print_summary(struct trussinfo *trussinf
 	fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
 	    "syscall", "seconds", "calls", "errors");
 	ncall = nerror = 0;
-	for (sc = syscalls; sc->name != NULL; sc++)
+	STAILQ_FOREACH(sc, &syscalls, entries)
 		if (sc->ncalls) {
 			fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
 			    sc->name, (intmax_t)sc->time.tv_sec,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510051808.t95I8a0n035052>