]> granicus.if.org Git - strace/commitdiff
Add a function for dumping iovec in msghdr used in sendmsg and recvmsg
authorMasatake YAMATO <yamato@redhat.com>
Wed, 15 Oct 2014 13:11:43 +0000 (22:11 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 1 Nov 2014 01:46:06 +0000 (01:46 +0000)
Here is an example session:

    $ ./strace -e write=all ip link change dev enp0s25 mtu 1501 > /dev/null
    sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"(...
     * 40 bytes in buffer 0
     | 00000  28 00 00 00 10 00 05 00  d0 d9 aa 53 00 00 00 00  (..........S.... |
     | 00010  00 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  ................ |
     | 00020  08 00 04 00 dd 05 00 00                           ........         |
    ...

    $ ./strace -e read=all ip link show > /dev/null
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"...
     * 8192 bytes in buffer 0
     | 00000  34 00 00 00 02 00 00 00  00 00 00 00 ff 23 00 00  4............#.. |
     | 00010  ff ff ff ff 20 00 00 00  10 00 05 00 00 00 00 00  .... ........... |
    ...

* defs.h (dumpiov_in_msghdr): New prototype.
* net.c (extractmsghdr): New function derived from printmsghdr.
(printmsghdr): Use extractmsghdr.
(dumpiov_in_msghdr): New function.
* syscall.c (dumpio) [HAVE_SENDMSG]: Call dumpiov_in_msghdr for recvmsg
and sendmsg 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 5bfeb6b48212d294e68f1e8a81e74b728b4c1865..d41af968c03f75c09198bafd0bc345f0c233e95a 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -673,6 +673,7 @@ extern int printargs_ld(struct tcb *);
 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(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 46c491f8f6d78763c90f8fdcf20842d418c1dbae..a0e90a8fae5f92d2dbf52ef5271f27e4b67dba4e 100644 (file)
--- a/net.c
+++ b/net.c
@@ -392,33 +392,47 @@ struct mmsghdr32 {
        uint32_t /* unsigned */ msg_len;
 };
 
-static void
-printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
+static bool
+extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
 {
-       struct msghdr msg;
-
 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
        if (current_wordsize == 4) {
                struct msghdr32 msg32;
 
-               if (umove(tcp, addr, &msg32) < 0) {
-                       tprintf("%#lx", addr);
-                       return;
-               }
-               msg.msg_name       = (void*)(long)msg32.msg_name;
-               msg.msg_namelen    =              msg32.msg_namelen;
-               msg.msg_iov        = (void*)(long)msg32.msg_iov;
-               msg.msg_iovlen     =              msg32.msg_iovlen;
-               msg.msg_control    = (void*)(long)msg32.msg_control;
-               msg.msg_controllen =              msg32.msg_controllen;
-               msg.msg_flags      =              msg32.msg_flags;
+               if (umove(tcp, addr, &msg32) < 0)
+                       return false;
+               msg->msg_name       = (void*)(long)msg32.msg_name;
+               msg->msg_namelen    =              msg32.msg_namelen;
+               msg->msg_iov        = (void*)(long)msg32.msg_iov;
+               msg->msg_iovlen     =              msg32.msg_iovlen;
+               msg->msg_control    = (void*)(long)msg32.msg_control;
+               msg->msg_controllen =              msg32.msg_controllen;
+               msg->msg_flags      =              msg32.msg_flags;
        } else
 #endif
-       if (umove(tcp, addr, &msg) < 0) {
+       if (umove(tcp, addr, msg) < 0)
+               return false;
+       return true;
+}
+
+static void
+printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
+{
+       struct msghdr msg;
+
+       if (extractmsghdr(tcp, addr, &msg))
+               do_msghdr(tcp, &msg, data_size);
+       else
                tprintf("%#lx", addr);
-               return;
-       }
-       do_msghdr(tcp, &msg, data_size);
+}
+
+void
+dumpiov_in_msghdr(struct tcb *tcp, long addr)
+{
+       struct msghdr msg;
+
+       if (extractmsghdr(tcp, addr, &msg))
+               dumpiov(tcp, msg.msg_iovlen, (long)msg.msg_iov);
 }
 
 static void
index 135221bbcd1a9ab078d12b8ac98110824f48942e..fa761a95e20f29e3499220031c48a3f1ea954d9f 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -2497,6 +2497,10 @@ dumpio(struct tcb *tcp)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
                else if (func == sys_readv)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+#if HAVE_SENDMSG
+               else if (func == sys_recvmsg)
+                       dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+#endif
                return;
        }
        if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
@@ -2507,6 +2511,10 @@ dumpio(struct tcb *tcp)
                        dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
                else if (func == sys_writev)
                        dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+#if HAVE_SENDMSG
+               else if (func == sys_sendmsg)
+                       dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+#endif
                return;
        }
 }