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.
This commit is contained in:
parent
c13244b92e
commit
f083f6894c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286913
@ -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 @@ main(int ac, char **av)
|
||||
fprintf(trussinfo->outfile,
|
||||
"SIGNAL %u (%s)\n", trussinfo->pr_data,
|
||||
signame == NULL ? "?" : signame);
|
||||
free(signame);
|
||||
break;
|
||||
case S_EXIT:
|
||||
if (trussinfo->flags & COUNTONLY)
|
||||
|
@ -731,12 +731,15 @@ get_string(pid_t pid, void *addr, int max)
|
||||
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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
}
|
||||
#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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
}
|
||||
}
|
||||
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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
* 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, unsigned long *args, long retval,
|
||||
*/
|
||||
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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
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, unsigned long *args, long retval,
|
||||
*/
|
||||
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, unsigned long *args, long retval,
|
||||
!= -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, unsigned long *args, long retval,
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user