Add support for readv() and writev() to truss.

Sponsored by:	Netflix, Inc.
This commit is contained in:
Michael Tuexen 2018-01-13 13:59:35 +00:00
parent fd94177c70
commit ee6e58b26e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327919
2 changed files with 67 additions and 1 deletions

View File

@ -82,7 +82,7 @@ enum Argtype { None = 1, Hex, Octal, Int, UInt, LongHex, Name, Ptr, Stat, Stat11
Sockoptname, Msgflags, CapRights, PUInt, PQuadHex, Acltype,
Extattrnamespace, Minherit, Mlockall, Mountflags, Msync, Priowhich,
Ptraceop, Quotactlcmd, Reboothowto, Rtpriofunc, Schedpolicy, Schedparam,
PSig, Siginfo, Kevent11,
PSig, Siginfo, Kevent11, Iovec,
CloudABIAdvice, CloudABIClockID, ClouduABIFDSFlags,
CloudABIFDStat, CloudABIFileStat, CloudABIFileType,

View File

@ -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);