Author: tmunro
Date: Thu Dec 10 07:13:15 2020
New Revision: 368500
URL: https://svnweb.freebsd.org/changeset/base/368500

Log:
  truss: Add AIO syscalls.
  
  Display the arguments of aio_read(2), aio_write(2), aio_suspend(2),
  aio_error(2), aio_return(2), aio_cancel(2), aio_fsync(2), aio_mlock(2),
  aio_waitcomplete(2) and lio_listio(2) in human-readable form.
  
  Reviewed by:  asomers
  Differential Revision:        https://reviews.freebsd.org/D27518

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

Modified: head/usr.bin/truss/syscall.h
==============================================================================
--- head/usr.bin/truss/syscall.h        Thu Dec 10 05:50:45 2020        
(r368499)
+++ head/usr.bin/truss/syscall.h        Thu Dec 10 07:13:15 2020        
(r368500)
@@ -87,6 +87,7 @@ enum Argtype {
        /* Encoded scalar values. */
        Accessmode,
        Acltype,
+       AiofsyncOp,
        Atfd,
        Atflags,
        CapFcntlRights,
@@ -101,6 +102,7 @@ enum Argtype {
        Ioctl,
        Kldsymcmd,
        Kldunloadflags,
+       LioMode,
        Madvice,
        Minherit,
        Msgflags,
@@ -139,6 +141,8 @@ enum Argtype {
 
        /* Pointers to non-structures. */
        Ptr,
+       AiocbArray,
+       AiocbPointer,
        BinString,
        CapRights,
        ExecArgs,
@@ -157,6 +161,7 @@ enum Argtype {
        StringArray,
 
        /* Pointers to structures. */
+       Aiocb,
        Itimerval,
        Kevent,
        Kevent11,
@@ -168,6 +173,7 @@ enum Argtype {
        Schedparam,
        Sctpsndrcvinfo,
        Sigaction,
+       Sigevent,
        Siginfo,
        Sigset,
        Sockaddr,

Modified: head/usr.bin/truss/syscalls.c
==============================================================================
--- head/usr.bin/truss/syscalls.c       Thu Dec 10 05:50:45 2020        
(r368499)
+++ head/usr.bin/truss/syscalls.c       Thu Dec 10 07:13:15 2020        
(r368500)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
  * arguments.
  */
 
+#include <sys/aio.h>
 #include <sys/capsicum.h>
 #include <sys/types.h>
 #define        _WANT_FREEBSD11_KEVENT
@@ -125,6 +126,24 @@ static struct syscall decoded_syscalls[] = {
          .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
        { .name = "access", .ret_type = 1, .nargs = 2,
          .args = { { Name | IN, 0 }, { Accessmode, 1 } } },
+       { .name = "aio_cancel", .ret_type = 1, .nargs = 2,
+         .args = { { Int, 0 }, { Aiocb, 1 } } },
+       { .name = "aio_error", .ret_type = 1, .nargs = 1,
+         .args = { { Aiocb, 0 } } },
+       { .name = "aio_fsync", .ret_type = 1, .nargs = 2,
+         .args = { { AiofsyncOp, 0 }, { Aiocb, 1 } } },
+       { .name = "aio_mlock", .ret_type = 1, .nargs = 1,
+         .args = { { Aiocb, 0 } } },
+       { .name = "aio_read", .ret_type = 1, .nargs = 1,
+         .args = { { Aiocb, 0 } } },
+       { .name = "aio_return", .ret_type = 1, .nargs = 1,
+         .args = { { Aiocb, 0 } } },
+       { .name = "aio_suspend", .ret_type = 1, .nargs = 3,
+         .args = { { AiocbArray, 0 }, { Int, 1 }, { Timespec, 2 } } },
+       { .name = "aio_waitcomplete", .ret_type = 1, .nargs = 2,
+         .args = { { AiocbPointer | OUT, 0 }, { Timespec, 1 } } },
+       { .name = "aio_write", .ret_type = 1, .nargs = 1,
+         .args = { { Aiocb, 0 } } },
        { .name = "bind", .ret_type = 1, .nargs = 3,
          .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } },
        { .name = "bindat", .ret_type = 1, .nargs = 4,
@@ -324,6 +343,9 @@ static struct syscall decoded_syscalls[] = {
        { .name = "linkat", .ret_type = 1, .nargs = 5,
          .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 },
                    { Atflags, 4 } } },
+       { .name = "lio_listio", .ret_type = 1, .nargs = 4,
+         .args = { { LioMode, 0 }, { AiocbArray, 1 }, { Int, 2 },
+                   { Sigevent, 3 } } },
        { .name = "listen", .ret_type = 1, .nargs = 2,
          .args = { { Int, 0 }, { Int, 1 } } },
        { .name = "lseek", .ret_type = 2, .nargs = 3,
@@ -714,6 +736,21 @@ static struct xlat linux_socketcall_ops[] = {
        XEND
 };
 
+static struct xlat lio_modes[] = {
+       X(LIO_WAIT) X(LIO_NOWAIT)
+       XEND
+};
+
+static struct xlat lio_opcodes[] = {
+       X(LIO_WRITE) X(LIO_READ) X(LIO_NOP)
+       XEND
+};
+
+static struct xlat aio_fsync_ops[] = {
+       X(O_SYNC)
+       XEND
+};
+
 #undef X
 #define        X(a)    { CLOUDABI_##a, #a },
 
@@ -1333,6 +1370,59 @@ print_iovec(FILE *fp, struct trussinfo *trussinfo, uin
 }
 
 static void
+print_sigval(FILE *fp, union sigval *sv)
+{
+       fprintf(fp, "{ %d, %p }", sv->sival_int, sv->sival_ptr);
+}
+
+static void
+print_sigevent(FILE *fp, struct sigevent *se)
+{
+       fputs("{ sigev_notify=", fp);
+       switch (se->sigev_notify) {
+       case SIGEV_NONE:
+               fputs("SIGEV_NONE", fp);
+               break;
+       case SIGEV_SIGNAL:
+               fprintf(fp, "SIGEV_SIGNAL, sigev_signo=%s, sigev_value=",
+                               strsig2(se->sigev_signo));
+               print_sigval(fp, &se->sigev_value);
+               break;
+       case SIGEV_THREAD:
+               fputs("SIGEV_THREAD, sigev_value=", fp);
+               print_sigval(fp, &se->sigev_value);
+               break;
+       case SIGEV_KEVENT:
+               fprintf(fp, "SIGEV_KEVENT, sigev_notify_kqueue=%d, 
sigev_notify_kevent_flags=",
+                               se->sigev_notify_kqueue);
+               print_mask_arg(sysdecode_kevent_flags, fp, 
se->sigev_notify_kevent_flags);
+               break;
+       case SIGEV_THREAD_ID:
+               fprintf(fp, "SIGEV_THREAD_ID, sigev_notify_thread_id=%d, 
sigev_signo=%s, sigev_value=",
+                               se->sigev_notify_thread_id, 
strsig2(se->sigev_signo));
+               print_sigval(fp, &se->sigev_value);
+               break;
+       default:
+               fprintf(fp, "%d", se->sigev_notify);
+               break;
+       }
+       fputs(" }", fp);
+}
+
+static void
+print_aiocb(FILE *fp, struct aiocb *cb)
+{
+       fprintf(fp, "{ %d,%jd,%p,%zu,%s,",
+                       cb->aio_fildes,
+                       cb->aio_offset,
+                       cb->aio_buf,
+                       cb->aio_nbytes,
+                       xlookup(lio_opcodes, cb->aio_lio_opcode));
+       print_sigevent(fp, &cb->aio_sigevent);
+       fputs(" }", fp);
+}
+
+static void
 print_gen_cmsg(FILE *fp, struct cmsghdr *cmsghdr)
 {
        u_char *q;
@@ -2115,6 +2205,15 @@ print_arg(struct syscall_args *sc, unsigned long *args
                        print_pointer(fp, args[sc->offset]);
                break;
        }
+       case Sigevent: {
+               struct sigevent se;
+
+               if (get_struct(pid, args[sc->offset], &se, sizeof(se)) != -1)
+                       print_sigevent(fp, &se);
+               else
+                       print_pointer(fp, args[sc->offset]);
+               break;
+       }
        case Kevent: {
                /*
                 * XXX XXX: The size of the array is determined by either the
@@ -2481,6 +2580,12 @@ print_arg(struct syscall_args *sc, unsigned long *args
                print_integer_arg(sysdecode_kldunload_flags, fp,
                    args[sc->offset]);
                break;
+       case AiofsyncOp:
+               fputs(xlookup(aio_fsync_ops, args[sc->offset]), fp);
+               break;
+       case LioMode:
+               fputs(xlookup(lio_modes, args[sc->offset]), fp);
+               break;
        case Madvice:
                print_integer_arg(sysdecode_madvice, fp, args[sc->offset]);
                break;
@@ -2618,6 +2723,67 @@ print_arg(struct syscall_args *sc, unsigned long *args
                print_iovec(fp, trussinfo, args[sc->offset],
                    (int)args[sc->offset + 1]);
                break;
+       case Aiocb: {
+               struct aiocb cb;
+
+               if (get_struct(pid, args[sc->offset], &cb, sizeof(cb)) != -1)
+                       print_aiocb(fp, &cb);
+               else
+                       print_pointer(fp, args[sc->offset]);
+               break;
+       }
+       case AiocbArray: {
+               /*
+                * Print argment as an array of pointers to struct aiocb, where
+                * the next syscall argument is the number of elements.
+                */
+               uintptr_t cbs[16];
+               unsigned int nent;
+               bool truncated;
+
+               nent = args[sc->offset + 1];
+               truncated = false;
+               if (nent > nitems(cbs)) {
+                       nent = nitems(cbs);
+                       truncated = true;
+               }
+
+               if (get_struct(pid, args[sc->offset], cbs, sizeof(uintptr_t) * 
nent) != -1) {
+                       unsigned int i;
+                       fputs("[", fp);
+                       for (i = 0; i < nent; ++i) {
+                               struct aiocb cb;
+                               if (i > 0)
+                                       fputc(',', fp);
+                               if (get_struct(pid, cbs[i], &cb, sizeof(cb)) != 
-1)
+                                       print_aiocb(fp, &cb);
+                               else
+                                       print_pointer(fp, cbs[i]);
+                       }
+                       if (truncated)
+                               fputs(",...", fp);
+                       fputs("]", fp);
+               } else
+                       print_pointer(fp, args[sc->offset]);
+               break;
+       }
+       case AiocbPointer: {
+               /*
+                * aio_waitcomplete(2) assigns a pointer to a pointer to struct
+                * aiocb, so we need to handle the extra layer of indirection.
+                */
+               uintptr_t cbp;
+               struct aiocb cb;
+
+               if (get_struct(pid, args[sc->offset], &cbp, sizeof(cbp)) != -1) 
{
+                       if (get_struct(pid, cbp, &cb, sizeof(cb)) != -1)
+                               print_aiocb(fp, &cb);
+                       else
+                               print_pointer(fp, cbp);
+               } else
+                       print_pointer(fp, args[sc->offset]);
+               break;
+       }
        case Sctpsndrcvinfo: {
                struct sctp_sndrcvinfo info;
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to