svn commit: r286913 - head/usr.bin/truss

John Baldwin jhb at FreeBSD.org
Wed Aug 19 00:49:51 UTC 2015


Author: jhb
Date: Wed Aug 19 00:49:50 2015
New Revision: 286913
URL: https://svnweb.freebsd.org/changeset/base/286913

Log:
  Change the argument formatting function to use a stdio FILE object opened
  with open_memstream() to build the string for each argument.  This allows
  for more complicated argument building without resorting to intermediate
  malloc's, etc.
  
  Related, the strsig*() functions no longer return allocated strings but
  use a static global buffer instead.

Modified:
  head/usr.bin/truss/main.c
  head/usr.bin/truss/syscalls.c

Modified: head/usr.bin/truss/main.c
==============================================================================
--- head/usr.bin/truss/main.c	Wed Aug 19 00:26:54 2015	(r286912)
+++ head/usr.bin/truss/main.c	Wed Aug 19 00:49:50 2015	(r286913)
@@ -149,15 +149,13 @@ set_etype(struct trussinfo *trussinfo)
 char *
 strsig(int sig)
 {
-	char *ret;
+	static char tmp[64];
 
-	ret = NULL;
 	if (sig > 0 && sig < NSIG) {
-		asprintf(&ret, "SIG%s", sys_signame[sig]);
-		if (ret == NULL)
-			return (NULL);
+		snprintf(tmp, sizeof(tmp), "SIG%s", sys_signame[sig]);
+		return (tmp);
 	}
-	return (ret);
+	return (NULL);
 }
 
 int
@@ -340,7 +338,6 @@ START_TRACE:
 			fprintf(trussinfo->outfile,
 			    "SIGNAL %u (%s)\n", trussinfo->pr_data,
 			    signame == NULL ? "?" : signame);
-			free(signame);
 			break;
 		case S_EXIT:
 			if (trussinfo->flags & COUNTONLY)

Modified: head/usr.bin/truss/syscalls.c
==============================================================================
--- head/usr.bin/truss/syscalls.c	Wed Aug 19 00:26:54 2015	(r286912)
+++ head/usr.bin/truss/syscalls.c	Wed Aug 19 00:49:50 2015	(r286913)
@@ -731,12 +731,15 @@ get_string(pid_t pid, void *addr, int ma
 static char *
 strsig2(int sig)
 {
-	char *tmp;
+	static char tmp[sizeof(int) * 3 + 1];
+	char *ret;
 
-	tmp = strsig(sig);
-	if (tmp == NULL)
-		asprintf(&tmp, "%d", sig);
-	return (tmp);
+	ret = strsig(sig);
+	if (ret == NULL) {
+		snprintf(tmp, sizeof(tmp), "%d", sig);
+		ret = tmp;
+	}
+	return (ret);
 }
 
 /*
@@ -753,32 +756,34 @@ char *
 print_arg(struct syscall_args *sc, unsigned long *args, long retval,
     struct trussinfo *trussinfo)
 {
+	FILE *fp;
 	char *tmp;
+	size_t tmplen;
 	pid_t pid;
 
-	tmp = NULL;
+	fp = open_memstream(&tmp, &tmplen);
 	pid = trussinfo->pid;
 	switch (sc->type & ARG_MASK) {
 	case Hex:
-		asprintf(&tmp, "0x%x", (int)args[sc->offset]);
+		fprintf(fp, "0x%x", (int)args[sc->offset]);
 		break;
 	case Octal:
-		asprintf(&tmp, "0%o", (int)args[sc->offset]);
+		fprintf(fp, "0%o", (int)args[sc->offset]);
 		break;
 	case Int:
-		asprintf(&tmp, "%d", (int)args[sc->offset]);
+		fprintf(fp, "%d", (int)args[sc->offset]);
 		break;
 	case LongHex:
-		asprintf(&tmp, "0x%lx", args[sc->offset]);
+		fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	case Long:
-		asprintf(&tmp, "%ld", args[sc->offset]);
+		fprintf(fp, "%ld", args[sc->offset]);
 		break;
 	case Name: {
 		/* NULL-terminated string. */
 		char *tmp2;
 		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
-		asprintf(&tmp, "\"%s\"", tmp2);
+		fprintf(fp, "\"%s\"", tmp2);
 		free(tmp2);
 		break;
 	}
@@ -814,11 +819,11 @@ print_arg(struct syscall_args *sc, unsig
 				len--;
 				truncated = 1;
 			};
-			asprintf(&tmp, "\"%s\"%s", tmp3, truncated ?
+			fprintf(fp, "\"%s\"%s", tmp3, truncated ?
 			    "..." : "");
 			free(tmp3);
 		} else {
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		}
 		break;
 	}
@@ -857,37 +862,35 @@ print_arg(struct syscall_args *sc, unsig
 	}
 #ifdef __LP64__
 	case Quad:
-		asprintf(&tmp, "0x%lx", args[sc->offset]);
+		fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 #else
 	case Quad: {
 		unsigned long long ll;
 		ll = *(unsigned long long *)(args + sc->offset);
-		asprintf(&tmp, "0x%llx", ll);
+		fprintf(fp, "0x%llx", ll);
 		break;
 	}
 #endif
 	case Ptr:
-		asprintf(&tmp, "0x%lx", args[sc->offset]);
+		fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	case Readlinkres: {
 		char *tmp2;
-		if (retval == -1) {
-			tmp = strdup("");
+		if (retval == -1)
 			break;
-		}
 		tmp2 = get_string(pid, (void*)args[sc->offset], retval);
-		asprintf(&tmp, "\"%s\"", tmp2);
+		fprintf(fp, "\"%s\"", tmp2);
 		free(tmp2);
 		break;
 	}
 	case Ioctl: {
 		const char *temp = ioctlname(args[sc->offset]);
 		if (temp)
-			tmp = strdup(temp);
+			fputs(temp, fp);
 		else {
 			unsigned long arg = args[sc->offset];
-			asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
+			fprintf(fp, "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) : '?',
@@ -899,22 +902,19 @@ print_arg(struct syscall_args *sc, unsig
 		struct timespec ts;
 		if (get_struct(pid, (void *)args[sc->offset], &ts,
 		    sizeof(ts)) != -1)
-			asprintf(&tmp, "{ %ld.%09ld }", (long)ts.tv_sec,
+			fprintf(fp, "{ %ld.%09ld }", (long)ts.tv_sec,
 			    ts.tv_nsec);
 		else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Timespec2: {
 		struct timespec ts[2];
-		FILE *fp;
-		size_t len;
 		const char *sep;
 		unsigned int i;
 
 		if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts))
 		    != -1) {
-			fp = open_memstream(&tmp, &len);
 			fputs("{ ", fp);
 			sep = "";
 			for (i = 0; i < nitems(ts); i++) {
@@ -934,43 +934,42 @@ print_arg(struct syscall_args *sc, unsig
 				}
 			}
 			fputs(" }", fp);
-			fclose(fp);
 		} else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	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,
+			fprintf(fp, "{ %ld.%06ld }", (long)tv.tv_sec,
 			    tv.tv_usec);
 		else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Timeval2: {
 		struct timeval tv[2];
 		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
 		    != -1)
-			asprintf(&tmp, "{ %ld.%06ld, %ld.%06ld }",
+			fprintf(fp, "{ %ld.%06ld, %ld.%06ld }",
 			    (long)tv[0].tv_sec, tv[0].tv_usec,
 			    (long)tv[1].tv_sec, tv[1].tv_usec);
 		else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Itimerval: {
 		struct itimerval itv;
 		if (get_struct(pid, (void *)args[sc->offset], &itv,
 		    sizeof(itv)) != -1)
-			asprintf(&tmp, "{ %ld.%06ld, %ld.%06ld }",
+			fprintf(fp, "{ %ld.%06ld, %ld.%06ld }",
 			    (long)itv.it_interval.tv_sec,
 			    itv.it_interval.tv_usec,
 			    (long)itv.it_value.tv_sec,
 			    itv.it_value.tv_usec);
 		else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case LinuxSockArgs:
@@ -978,11 +977,11 @@ print_arg(struct syscall_args *sc, unsig
 		struct linux_socketcall_args largs;
 		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
 		    sizeof(largs)) != -1)
-			asprintf(&tmp, "{ %s, 0x%lx }",
+			fprintf(fp, "{ %s, 0x%lx }",
 			    lookup(linux_socketcall_ops, largs.what, 10),
 			    (long unsigned int)largs.args);
 		else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Pollfd: {
@@ -992,37 +991,23 @@ print_arg(struct syscall_args *sc, unsig
 		 * syscall.
 		 */
 		struct pollfd *pfd;
-		int numfds = args[sc->offset+1];
-		int bytes = sizeof(struct pollfd) * numfds;
-		int i, tmpsize, u, used;
-		const int per_fd = 100;
+		int numfds = args[sc->offset + 1];
+		size_t bytes = sizeof(struct pollfd) * numfds;
+		int i;
 
 		if ((pfd = malloc(bytes)) == NULL)
-			err(1, "Cannot malloc %d bytes for pollfd array",
+			err(1, "Cannot malloc %zu 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);
-
-			tmp[used++] = '{';
-			tmp[used++] = ' ';
+			fputs("{", fp);
 			for (i = 0; i < numfds; i++) {
-
-				u = snprintf(tmp + used, per_fd, "%s%d/%s",
-				    i > 0 ? " " : "", pfd[i].fd,
+				fprintf(fp, " %d/%s", pfd[i].fd,
 				    xlookup_bits(poll_flags, pfd[i].events));
-				if (u > 0)
-					used += u < per_fd ? u : per_fd;
 			}
-			tmp[used++] = ' ';
-			tmp[used++] = '}';
-			tmp[used++] = '\0';
+			fputs(" }", fp);
 		} else {
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		}
 		free(pfd);
 		break;
@@ -1035,108 +1020,86 @@ print_arg(struct syscall_args *sc, unsig
 		 */
 		fd_set *fds;
 		int numfds = args[0];
-		int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
-		int i, tmpsize, u, used;
-		const int per_fd = 20;
+		size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
+		int i;
 
 		if ((fds = malloc(bytes)) == NULL)
-			err(1, "Cannot malloc %d bytes for fd_set array",
+			err(1, "Cannot malloc %zu 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);
-
-			tmp[used++] = '{';
-			tmp[used++] = ' ';
+			fputs("{", fp);
 			for (i = 0; i < numfds; i++) {
-				if (FD_ISSET(i, fds)) {
-					u = snprintf(tmp + used, per_fd, "%d ",
-					    i);
-					if (u > 0)
-						used += u < per_fd ? u : per_fd;
-				}
+				if (FD_ISSET(i, fds))
+					fprintf(fp, " %d", i);
 			}
-			tmp[used++] = '}';
-			tmp[used++] = '\0';
+			fputs(" }", fp);
 		} else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		free(fds);
 		break;
 	}
 	case Signal:
-		tmp = strsig2(args[sc->offset]);
+		fputs(strsig2(args[sc->offset]), fp);
 		break;
 	case Sigset: {
 		long sig;
 		sigset_t ss;
-		int i, used;
-		char *signame;
+		int i, first;
 
 		sig = args[sc->offset];
 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
 		    sizeof(ss)) == -1) {
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 			break;
 		}
-		tmp = malloc(sys_nsig * 8 + 2); /* 7 bytes avg per signal name */
-		used = 0;
-		tmp[used++] = '{';
-		tmp[used++] = ' ';
+		fputs("{ ", fp);
+		first = 1;
 		for (i = 1; i < sys_nsig; i++) {
 			if (sigismember(&ss, i)) {
-				signame = strsig(i);
-				used += sprintf(tmp + used, "%s|", signame);
-				free(signame);
+				fprintf(fp, "%s%s", !first ? "|" : "",
+				    strsig(i));
+				first = 0;
 			}
 		}
-		if (tmp[used - 1] == '|')
-			used--;
-		tmp[used++] = ' ';
-		tmp[used++] = '}';
-		tmp[used++] = '\0';
+		if (!first)
+			fputc(' ', fp);
+		fputc('}', fp);
 		break;
 	}
 	case Sigprocmask: {
-		tmp = strdup(xlookup(sigprocmask_ops, args[sc->offset]));
+		fputs(xlookup(sigprocmask_ops, args[sc->offset]), fp);
 		break;
 	}
 	case Fcntlflag: {
 		/* 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]));
+			fputs(xlookup_bits(fcntlfd_arg, args[sc->offset]), fp);
 			break;
 		case F_SETFL:
-			tmp = strdup(xlookup_bits(fcntlfl_arg,
-			    args[sc->offset]));
+			fputs(xlookup_bits(fcntlfl_arg, args[sc->offset]), fp);
 			break;
 		case F_GETFD:
 		case F_GETFL:
 		case F_GETOWN:
-			tmp = strdup("");
 			break;
 		default:
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 			break;
 		}
 		break;
 	}
 	case Open:
-		tmp = strdup(xlookup_bits(open_flags, args[sc->offset]));
+		fputs(xlookup_bits(open_flags, args[sc->offset]), fp);
 		break;
 	case Fcntl:
-		tmp = strdup(xlookup(fcntl_arg, args[sc->offset]));
+		fputs(xlookup(fcntl_arg, args[sc->offset]), fp);
 		break;
 	case Mprot:
-		tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset]));
+		fputs(xlookup_bits(mprot_flags, args[sc->offset]), fp);
 		break;
 	case Mmapflags: {
-		char *base, *alignstr;
 		int align, flags;
 
 		/*
@@ -1150,59 +1113,46 @@ print_arg(struct syscall_args *sc, unsig
 		align = args[sc->offset] & MAP_ALIGNMENT_MASK;
 		if (align != 0) {
 			if (align == MAP_ALIGNED_SUPER)
-				alignstr = strdup("MAP_ALIGNED_SUPER");
+				fputs("MAP_ALIGNED_SUPER", fp);
 			else
-				asprintf(&alignstr, "MAP_ALIGNED(%d)",
+				fprintf(fp, "MAP_ALIGNED(%d)",
 				    align >> MAP_ALIGNMENT_SHIFT);
-			if (flags == 0) {
-				tmp = alignstr;
+			if (flags == 0)
 				break;
-			}
-		} else
-			alignstr = NULL;
-		base = strdup(xlookup_bits(mmap_flags, flags));
-		if (alignstr == NULL) {
-			tmp = base;
-			break;
+			fputc('|', fp);
 		}
-		asprintf(&tmp, "%s|%s", alignstr, base);
-		free(alignstr);
-		free(base);
+		fputs(xlookup_bits(mmap_flags, flags), fp);
 		break;
 	}
 	case Whence:
-		tmp = strdup(xlookup(whence_arg, args[sc->offset]));
+		fputs(xlookup(whence_arg, args[sc->offset]), fp);
 		break;
 	case Sockdomain:
-		tmp = strdup(xlookup(sockdomain_arg, args[sc->offset]));
+		fputs(xlookup(sockdomain_arg, args[sc->offset]), fp);
 		break;
 	case Socktype: {
-		FILE *fp;
-		size_t len;
 		int type, flags;
 
 		flags = args[sc->offset] & (SOCK_CLOEXEC | SOCK_NONBLOCK);
 		type = args[sc->offset] & ~flags;
-		fp = open_memstream(&tmp, &len);
 		fputs(xlookup(socktype_arg, type), fp);
 		if (flags & SOCK_CLOEXEC)
 			fprintf(fp, "|SOCK_CLOEXEC");
 		if (flags & SOCK_NONBLOCK)
 			fprintf(fp, "|SOCK_NONBLOCK");
-		fclose(fp);
 		break;
 	}
 	case Shutdown:
-		tmp = strdup(xlookup(shutdown_arg, args[sc->offset]));
+		fputs(xlookup(shutdown_arg, args[sc->offset]), fp);
 		break;
 	case Resource:
-		tmp = strdup(xlookup(resource_arg, args[sc->offset]));
+		fputs(xlookup(resource_arg, args[sc->offset]), fp);
 		break;
 	case Pathconf:
-		tmp = strdup(xlookup(pathconf_arg, args[sc->offset]));
+		fputs(xlookup(pathconf_arg, args[sc->offset]), fp);
 		break;
 	case Rforkflags:
-		tmp = strdup(xlookup_bits(rfork_flags, args[sc->offset]));
+		fputs(xlookup_bits(rfork_flags, args[sc->offset]), fp);
 		break;
 	case Sockaddr: {
 		struct sockaddr_storage ss;
@@ -1211,19 +1161,20 @@ print_arg(struct syscall_args *sc, unsig
 		struct sockaddr_in6 *lsin6;
 		struct sockaddr_un *sun;
 		struct sockaddr *sa;
-		char *p;
 		u_char *q;
-		int i;
 
 		if (args[sc->offset] == 0) {
-			asprintf(&tmp, "NULL");
+			fputs("NULL", fp);
 			break;
 		}
 
 		/* yuck: get ss_len */
 		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
-		    sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
-			err(1, "get_struct %p", (void *)args[sc->offset]);
+		    sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) {
+			fprintf(fp, "0x%lx", args[sc->offset]);
+			break;
+		}
+
 		/*
 		 * If ss_len is 0, then try to guess from the sockaddr type.
 		 * AF_UNIX may be initialized incorrectly, so always frob
@@ -1234,73 +1185,71 @@ print_arg(struct syscall_args *sc, unsig
 			case AF_INET:
 				ss.ss_len = sizeof(*lsin);
 				break;
+			case AF_INET6:
+				ss.ss_len = sizeof(*lsin6);
+				break;
 			case AF_UNIX:
 				ss.ss_len = sizeof(*sun);
 				break;
 			default:
-				/* hurrrr */
 				break;
 			}
 		}
-		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
+		if (ss.ss_len != 0 &&
+		    get_struct(pid, (void *)args[sc->offset], (void *)&ss,
 		    ss.ss_len) == -1) {
-			err(2, "get_struct %p", (void *)args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
+			break;
 		}
 
 		switch (ss.ss_family) {
 		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,
+			fprintf(fp, "{ 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,
+			fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
 			    htons(lsin6->sin6_port));
 			break;
 		case AF_UNIX:
 			sun = (struct sockaddr_un *)&ss;
-			asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
+			fprintf(fp, "{ AF_UNIX \"%s\" }", sun->sun_path);
 			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)), "");
-			if (tmp != NULL) {
-				p = tmp + i;
-				for (q = (u_char *)&sa->sa_data;
-				    q < (u_char *)sa + sa->sa_len; q++)
-					p += sprintf(p, " %#02x,", *q);
-			}
+			fprintf(fp,
+			    "{ sa_len = %d, sa_family = %d, sa_data = {",
+			    (int)sa->sa_len, (int)sa->sa_family);
+			for (q = (u_char *)sa->sa_data;
+			     q < (u_char *)sa + sa->sa_len; q++)
+				fprintf(fp, "%s 0x%02x",
+				    q == (u_char *)sa->sa_data ? "" : ",",
+				    *q);
+			fputs(" } }", fp);
 		}
 		break;
 	}
 	case Sigaction: {
 		struct sigaction sa;
-		char *hand;
-		const char *h;
 
 		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
 		    != -1) {
-			asprintf(&hand, "%p", sa.sa_handler);
+			fputs("{ ", fp);
 			if (sa.sa_handler == SIG_DFL)
-				h = "SIG_DFL";
+				fputs("SIG_DFL", fp);
 			else if (sa.sa_handler == SIG_IGN)
-				h = "SIG_IGN";
+				fputs("SIG_IGN", fp);
 			else
-				h = hand;
-
-			asprintf(&tmp, "{ %s %s ss_t }", h,
+				fprintf(fp, "%p", sa.sa_handler);
+			fprintf(fp, " %s ss_t }",
 			    xlookup_bits(sigaction_flags, sa.sa_flags));
-			free(hand);
 		} else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Kevent: {
@@ -1313,48 +1262,36 @@ print_arg(struct syscall_args *sc, unsig
 		 */
 		struct kevent *ke;
 		int numevents = -1;
-		int bytes = 0;
-		int i, tmpsize, u, used;
-		const int per_ke = 100;
+		size_t bytes;
+		int i;
 
 		if (sc->offset == 1)
 			numevents = args[sc->offset+1];
 		else if (sc->offset == 3 && retval != -1)
 			numevents = retval;
 
-		if (numevents >= 0)
+		if (numevents >= 0) {
 			bytes = sizeof(struct kevent) * numevents;
-		if ((ke = malloc(bytes)) == NULL)
-			err(1, "Cannot malloc %d bytes for kevent array",
-			    bytes);
+			if ((ke = malloc(bytes)) == NULL)
+				err(1,
+				    "Cannot malloc %zu bytes for kevent array",
+				    bytes);
+		} else
+			ke = NULL;
 		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);
-
-			tmp[used++] = '{';
-			tmp[used++] = ' ';
-			for (i = 0; i < numevents; i++) {
-				u = snprintf(tmp + used, per_ke,
-				    "%s%p,%s,%s,%d,%p,%p",
-				    i > 0 ? " " : "",
+			fputc('{', fp);
+			for (i = 0; i < numevents; i++)
+				fprintf(fp, " %p,%s,%s,%d,%p,%p",
 				    (void *)ke[i].ident,
 				    xlookup(kevent_filters, ke[i].filter),
 				    xlookup_bits(kevent_flags, ke[i].flags),
 				    ke[i].fflags,
 				    (void *)ke[i].data,
 				    (void *)ke[i].udata);
-				if (u > 0)
-					used += u < per_ke ? u : per_ke;
-			}
-			tmp[used++] = ' ';
-			tmp[used++] = '}';
-			tmp[used++] = '\0';
+			fputs(" }", fp);
 		} else {
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		}
 		free(ke);
 		break;
@@ -1365,12 +1302,12 @@ print_arg(struct syscall_args *sc, unsig
 		    != -1) {
 			char mode[12];
 			strmode(st.st_mode, mode);
-			asprintf(&tmp,
+			fprintf(fp,
 			    "{ 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]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		}
 		break;
 	}
@@ -1378,82 +1315,82 @@ print_arg(struct syscall_args *sc, unsig
 		struct rusage ru;
 		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
 		    != -1) {
-			asprintf(&tmp,
+			fprintf(fp,
 			    "{ 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
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Rlimit: {
 		struct rlimit rl;
 		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
 		    != -1) {
-			asprintf(&tmp, "{ cur=%ju,max=%ju }",
+			fprintf(fp, "{ cur=%ju,max=%ju }",
 			    rl.rlim_cur, rl.rlim_max);
 		} else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case ExitStatus: {
-		char *signame;
 		int status;
-		signame = NULL;
+
 		if (get_struct(pid, (void *)args[sc->offset], &status,
 		    sizeof(status)) != -1) {
+			fputs("{ ", fp);
 			if (WIFCONTINUED(status))
-				tmp = strdup("{ CONTINUED }");
+				fputs("CONTINUED", fp);
 			else if (WIFEXITED(status))
-				asprintf(&tmp, "{ EXITED,val=%d }",
+				fprintf(fp, "EXITED,val=%d",
 				    WEXITSTATUS(status));
 			else if (WIFSIGNALED(status))
-				asprintf(&tmp, "{ SIGNALED,sig=%s%s }",
-				    signame = strsig2(WTERMSIG(status)),
+				fprintf(fp, "SIGNALED,sig=%s%s",
+				    strsig2(WTERMSIG(status)),
 				    WCOREDUMP(status) ? ",cored" : "");
 			else
-				asprintf(&tmp, "{ STOPPED,sig=%s }",
-				    signame = strsig2(WTERMSIG(status)));
+				fprintf(fp, "STOPPED,sig=%s",
+				    strsig2(WTERMSIG(status)));
+			fputs(" }", fp);
 		} else
-			asprintf(&tmp, "0x%lx", args[sc->offset]);
-		free(signame);
+			fprintf(fp, "0x%lx", args[sc->offset]);
 		break;
 	}
 	case Waitoptions:
-		tmp = strdup(xlookup_bits(wait_options, args[sc->offset]));
+		fputs(xlookup_bits(wait_options, args[sc->offset]), fp);
 		break;
 	case Idtype:
-		tmp = strdup(xlookup(idtype_arg, args[sc->offset]));
+		fputs(xlookup(idtype_arg, args[sc->offset]), fp);
 		break;
 	case Procctl:
-		tmp = strdup(xlookup(procctl_arg, args[sc->offset]));
+		fputs(xlookup(procctl_arg, args[sc->offset]), fp);
 		break;
 	case Umtxop:
-		tmp = strdup(xlookup(umtx_ops, args[sc->offset]));
+		fputs(xlookup(umtx_ops, args[sc->offset]), fp);
 		break;
 	case Atfd:
 		if ((int)args[sc->offset] == AT_FDCWD)
-			tmp = strdup("AT_FDCWD");
+			fputs("AT_FDCWD", fp);
 		else
-			asprintf(&tmp, "%d", (int)args[sc->offset]);
+			fprintf(fp, "%d", (int)args[sc->offset]);
 		break;
 	case Atflags:
-		tmp = strdup(xlookup_bits(at_flags, args[sc->offset]));
+		fputs(xlookup_bits(at_flags, args[sc->offset]), fp);
 		break;
 	case Accessmode:
 		if (args[sc->offset] == F_OK)
-			tmp = strdup("F_OK");
+			fputs("F_OK", fp);
 		else
-			tmp = strdup(xlookup_bits(access_modes,
-				args[sc->offset]));
+			fputs(xlookup_bits(access_modes, args[sc->offset]), fp);
 		break;
 	case Sysarch:
-		tmp = strdup(xlookup(sysarch_ops, args[sc->offset]));
+		fputs(xlookup(sysarch_ops, args[sc->offset]), fp);
 		break;
 	default:
 		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
 	}
+	fclose(fp);
 	return (tmp);
 }
 


More information about the svn-src-all mailing list