From ee6e58b26e344c1d7fd4c87486f7f73402ead44c Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 13 Jan 2018 13:59:35 +0000 Subject: Add support for readv() and writev() to truss. Sponsored by: Netflix, Inc. --- usr.bin/truss/syscalls.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'usr.bin/truss/syscalls.c') diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index d8316dc30918..317677273ff6 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -386,6 +386,8 @@ static struct syscall decoded_syscalls[] = { .args = { { Name, 0 }, { Quotactlcmd, 1 }, { Int, 2 }, { Ptr, 3 } } }, { .name = "read", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { BinString | OUT, 1 }, { Sizet, 2 } } }, + { .name = "readv", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Iovec, 1 }, { Int, 2 } } }, { .name = "readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Sizet, 2 } } }, { .name = "readlinkat", .ret_type = 1, .nargs = 4, @@ -520,6 +522,8 @@ static struct syscall decoded_syscalls[] = { { Siginfo | OUT, 5 } } }, { .name = "write", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 } } }, + { .name = "writev", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Iovec, 1 }, { Int, 2 } } }, /* Linux ABI */ { .name = "linux_access", .ret_type = 1, .nargs = 2, @@ -2139,6 +2143,68 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval, fprintf(fp, "0x%lx", args[sc->offset]); break; } +#define IOV_LIMIT 26 + case Iovec: { + /* + * Print argument as an array of struct iovec, where the next + * syscall argument is the number of elements of the array. + */ + struct iovec iov[IOV_LIMIT]; + size_t max_string = trussinfo->strsize; + char tmp2[max_string + 1], *tmp3; + size_t len; + int i, iovcnt; + bool buf_truncated, iov_truncated; + + iovcnt = args[sc->offset + 1]; + if (iovcnt <= 0) { + fprintf(fp, "0x%lx", args[sc->offset]); + break; + } + if (iovcnt > IOV_LIMIT) { + iovcnt = IOV_LIMIT; + iov_truncated = true; + } else { + iov_truncated = false; + } + if (get_struct(pid, (void *)args[sc->offset], + &iov, iovcnt * sizeof(struct iovec)) == -1) { + fprintf(fp, "0x%lx", args[sc->offset]); + break; + } + + fprintf(fp, "%s", "["); + for (i = 0; i < iovcnt; i++) { + len = iov[i].iov_len; + if (len > max_string) { + len = max_string; + buf_truncated = true; + } else { + buf_truncated = false; + } + fprintf(fp, "%s{", (i > 0) ? "," : ""); + if (len && get_struct(pid, iov[i].iov_base, &tmp2, len) + != -1) { + tmp3 = malloc(len * 4 + 1); + while (len) { + if (strvisx(tmp3, tmp2, len, + VIS_CSTYLE|VIS_TAB|VIS_NL) <= + (int)max_string) + break; + len--; + buf_truncated = true; + } + fprintf(fp, "\"%s\"%s", tmp3, + buf_truncated ? "..." : ""); + free(tmp3); + } else { + fprintf(fp, "0x%p", iov[i].iov_base); + } + fprintf(fp, ",%zu}", iov[i].iov_len); + } + fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]"); + break; + } case CloudABIAdvice: fputs(xlookup(cloudabi_advice, args[sc->offset]), fp); -- cgit v1.2.3