]> granicus.if.org Git - strace/commitdiff
Add functions for dumping iovecs in mmsghdr used in sendmmsg and recvmmsg
authorMasatake YAMATO <yamato@redhat.com>
Thu, 6 Nov 2014 16:23:26 +0000 (01:23 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 11 Nov 2014 15:44:24 +0000 (15:44 +0000)
This patch is similar to what I did in commit
02f9f6b386741a52f58e1b31ad4e7fff60781ef8.
That commit was for sendmsg and recvmsg system calls.
This one is for sendmmsg and recvmmsg system calls.

* defs.h (dumpiov_in_mmsghdr): New declaration.
* net.c (extractmmsghdr): New function derived from printmmsghdr.
(printmmsghdr): Use it.
(dumpiov_in_mmsghdr): New function.
* syscall.c (dumpio) [HAVE_SENDMSG]: Call dumpiov_in_mmsghdr
for recvmmsg and sendmmsg syscalls.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
defs.h
net.c
syscall.c

diff --git a/defs.h b/defs.h
index 8a10e0353d2bd98fa84cd3e57c7c10fa9077fa5e..708adf61631b99113677b9e7ed433beb9d6c896b 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -673,6 +673,7 @@ extern void addflags(const struct xlat *, int);
 extern int printflags(const struct xlat *, int, const char *);
 extern const char *sprintflags(const char *, const struct xlat *, int);
 extern void dumpiov_in_msghdr(struct tcb *, long);
+extern void dumpiov_in_mmsghdr(struct tcb *, long);
 extern void dumpiov(struct tcb *, int, long);
 extern void dumpstr(struct tcb *, long, int);
 extern void printstr(struct tcb *, long, long);
diff --git a/net.c b/net.c
index 9e9e1591b38b32b33ea20049117c5d8864f76d2d..f3f102e402e1f7c1e9cda474425abe8975595e5c 100644 (file)
--- a/net.c
+++ b/net.c
@@ -467,6 +467,29 @@ extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
        return true;
 }
 
+static bool
+extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
+{
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+       if (current_wordsize == 4) {
+               struct mmsghdr32 mmsg32;
+
+               addr += sizeof(struct mmsghdr32) * idx;
+               if (umove(tcp, addr, &mmsg32) < 0)
+                       return false;
+
+               copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
+               mmsg->msg_len = mmsg32.msg_len;
+       } else
+#endif
+       {
+               addr += sizeof(*mmsg) * idx;
+               if (umove(tcp, addr, mmsg) < 0)
+                       return false;
+       }
+       return true;
+}
+
 static void
 printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
 {
@@ -492,35 +515,13 @@ printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len
 {
        struct mmsghdr mmsg;
 
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
-       if (current_wordsize == 4) {
-               struct mmsghdr32 mmsg32;
-
-               addr += sizeof(mmsg32) * idx;
-               if (umove(tcp, addr, &mmsg32) < 0) {
-                       tprintf("%#lx", addr);
-                       return;
-               }
-               mmsg.msg_hdr.msg_name       = (void*)(long)mmsg32.msg_hdr.msg_name;
-               mmsg.msg_hdr.msg_namelen    =              mmsg32.msg_hdr.msg_namelen;
-               mmsg.msg_hdr.msg_iov        = (void*)(long)mmsg32.msg_hdr.msg_iov;
-               mmsg.msg_hdr.msg_iovlen     =              mmsg32.msg_hdr.msg_iovlen;
-               mmsg.msg_hdr.msg_control    = (void*)(long)mmsg32.msg_hdr.msg_control;
-               mmsg.msg_hdr.msg_controllen =              mmsg32.msg_hdr.msg_controllen;
-               mmsg.msg_hdr.msg_flags      =              mmsg32.msg_hdr.msg_flags;
-               mmsg.msg_len                =              mmsg32.msg_len;
-       } else
-#endif
-       {
-               addr += sizeof(mmsg) * idx;
-               if (umove(tcp, addr, &mmsg) < 0) {
-                       tprintf("%#lx", addr);
-                       return;
-               }
+       if (extractmmsghdr(tcp, addr, idx, &mmsg)) {
+               tprints("{");
+               do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
+               tprintf(", %u}", mmsg.msg_len);
        }
-       tprints("{");
-       do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
-       tprintf(", %u}", mmsg.msg_len);
+       else
+               tprintf("%#lx", addr);
 }
 
 static void
@@ -547,6 +548,22 @@ decode_mmsg(struct tcb *tcp, unsigned long msg_len)
        printflags(msg_flags, tcp->u_arg[3], "MSG_???");
 }
 
+void
+dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
+{
+       unsigned int len = tcp->u_rval;
+       unsigned int i;
+       struct mmsghdr mmsg;
+
+       for (i = 0; i < len; ++i) {
+               if (extractmmsghdr(tcp, addr, i, &mmsg)) {
+                       tprintf(" = %lu buffers in vector %u\n",
+                               (unsigned long)mmsg.msg_hdr.msg_iovlen, i);
+                       dumpiov(tcp, mmsg.msg_hdr.msg_iovlen,
+                               (long)mmsg.msg_hdr.msg_iov);
+               }
+       }
+}
 #endif /* HAVE_SENDMSG */
 
 /*
index fa761a95e20f29e3499220031c48a3f1ea954d9f..091626cec871899d28b0367da46276d67e564405 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -2500,6 +2500,8 @@ dumpio(struct tcb *tcp)
 #if HAVE_SENDMSG
                else if (func == sys_recvmsg)
                        dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+               else if (func == sys_recvmmsg)
+                       dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
 #endif
                return;
        }
@@ -2514,6 +2516,8 @@ dumpio(struct tcb *tcp)
 #if HAVE_SENDMSG
                else if (func == sys_sendmsg)
                        dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+               else if (func == sys_sendmmsg)
+                       dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
 #endif
                return;
        }