commit c614b5785876c46cb15fd3f340f739926e913859 Author: Andi Kleen Date: Wed Apr 6 15:12:41 2011 -0700 Fix io_submit decoding in strace strace didn't decode important fields in the iocb passed to io_submit. This patch changes the code to dump them all. Also I prefixed the fields with names to make it easier to read. diff --git a/desc.c b/desc.c index 2b9f30a..57dc755 100644 --- a/desc.c +++ b/desc.c @@ -806,6 +806,51 @@ sys_io_destroy(struct tcb *tcp) return 0; } +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x))) + +enum iocb_sub { + SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR +}; + +static const char * +iocb_cmd_lookup(unsigned cmd, enum iocb_sub *sub) +{ + static char buf[20]; + static struct { + const char *name; + enum iocb_sub sub; + } cmds[] = { + { "pread", SUB_COMMON }, + { "pwrite", SUB_COMMON }, + { "fsync", SUB_NONE }, + { "fdsync", SUB_NONE }, + { "op4", SUB_NONE }, + { "poll", SUB_POLL }, + { "noop", SUB_NONE }, + { "preadv", SUB_VECTOR }, + { "pwritev", SUB_VECTOR }, + }; + + if (cmd < ARRAY_SIZE(cmds)) { + *sub = cmds[cmd].sub; + return cmds[cmd].name; + } + *sub = SUB_NONE; + snprintf(buf, sizeof buf, "?%u?", cmd); + return buf; +} + +/* Not defined in libaio.h */ +#define IOCB_RESFD (1 << 0) + +static void +print_common_flags(struct iocb *iocb) +{ + if (iocb->u.c.flags & IOCB_RESFD) + tprintf("resfd=%d, ", iocb->u.c.resfd); + if (iocb->u.c.flags & ~IOCB_RESFD) + tprintf("flags=%x, ", iocb->u.c.flags); +} int sys_io_submit(struct tcb *tcp) { @@ -822,7 +867,9 @@ sys_io_submit(struct tcb *tcp) struct iocb *iocbp, **iocbs = (void *)tcp->u_arg[2]; for (i = 0; i < nr; i++, iocbs++) { + enum iocb_sub sub; struct iocb iocb; + int k; if (i == 0) tprintf("{"); else @@ -833,10 +880,45 @@ sys_io_submit(struct tcb *tcp) tprintf("{...}"); continue; } - tprintf("{%p, %u, %hu, %hu, %d}", - iocb.data, iocb.key, - iocb.aio_lio_opcode, - iocb.aio_reqprio, iocb.aio_fildes); + tprintf("{"); + if (iocb.data) + tprintf("data:%p, ", iocb.data); + if (iocb.key) + tprintf("key:%u, ", iocb.key); + tprintf("%s, ", iocb_cmd_lookup(iocb.aio_lio_opcode, &sub)); + if (iocb.aio_reqprio) + tprintf("reqprio:%d, ", iocb.aio_reqprio); + tprintf("filedes:%d", iocb.aio_fildes); + switch (sub) { + case SUB_COMMON: + tprintf(", buf:%p, nbytes:%lu, offset:%llx", + iocb.u.c.buf, + iocb.u.c.nbytes, + iocb.u.c.offset); + print_common_flags(&iocb); + break; + case SUB_VECTOR: + tprintf(", %llx, ", iocb.u.v.offset); + print_common_flags(&iocb); + for (k = 0; k < iocb.u.v.nr; k++) { + struct iovec iov; + tprintf("%s", k == 0 ? "" : ", "); + if (umove(tcp, (unsigned long)iocb.u.v.vec + + sizeof(struct iovec)*k, &iov)) + tprintf("{...}"); + else + tprintf("{ %p, %lu }", + iov.iov_base, + iov.iov_len); + } + break; + case SUB_POLL: + tprintf(", %x", iocb.u.poll.events); + break; + case SUB_NONE: + break; + } + tprintf("}"); } if (i) tprintf("}");