[PATCH 3/4] Add functions for dumping iovecs in mmsghdr used in sendmmsg and recvmmsg
Masatake YAMATO
yamato at redhat.com
Thu Nov 6 16:23:26 UTC 2014
This patch is similar to what I did in commit
02f9f6b386741a52f58e1b31ad4e7fff60781ef8. The commit was for sendmsg
and recvmsg system calls. This one is for sendmmsg and recvmmsg system
calls.
$ ./strace -f -e write=all tests/mmsg
...
[pid 6730] sendmmsg(3, <unfinished ...>
...
[pid 6730] <... sendmmsg resumed> ...
= 2 buffers in vector 0
* 3 bytes in buffer 0
| 00000 6f 6e 65 one |
* 3 bytes in buffer 1
| 00000 74 77 6f two |
= 1 buffers in vector 1
* 5 bytes in buffer 0
| 00000 74 68 72 65 65 three |
...
$ ./strace -f -e read=all tests/mmsg
...
[pid 6819] recvmmsg(4, <unfinished ...>
[pid 6820] sendmmsg(3, <unfinished ...>
[pid 6819] <... recvmmsg resumed> ...
= 2 buffers in vector 0
* 3 bytes in buffer 0
| 00000 6f 6e 65 one |
* 3 bytes in buffer 1
| 00000 74 77 6f two |
= 1 buffers in vector 1
* 5 bytes in buffer 0
| 00000 74 68 72 65 65 three |
...
* configure.ac (sendmmsg): Check sendmmsg system call.
* defs.h (dumpiov_in_mmsghdr): New declaration.
* net.c (extractmmsghdr0, extractmmsghdr): New helper functions do the
same as extractmsghdr but for mmsghdr.
(extractmsghdr): Use copy_from_msghdr32.
(dumpiov_in_mmsghdr): Do the same as dumpiov_in_msghdr but for mmsghdr.
(printmmsghdr): Simplified with using extractmmsghdr.
* syscall.c (dumpio): call dumpiov_in_mmsghdr if revmmsg or sendmmsg is
called.
Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
configure.ac | 1 +
defs.h | 1 +
net.c | 80 ++++++++++++++++++++++++++++++++++++++++--------------------
syscall.c | 8 ++++++
4 files changed, 63 insertions(+), 27 deletions(-)
diff --git a/configure.ac b/configure.ac
index 01df6f2..35d52ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -219,6 +219,7 @@ AC_CHECK_FUNCS(m4_normalize([
process_vm_readv
pwritev
sendmsg
+ sendmmsg
sigaction
stpcpy
strerror
diff --git a/defs.h b/defs.h
index d41af96..661de92 100644
--- a/defs.h
+++ b/defs.h
@@ -674,6 +674,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 53c2a02..68e7399 100644
--- a/net.c
+++ b/net.c
@@ -430,6 +430,36 @@ extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
return true;
}
+static bool
+extractmmsghdr0(struct tcb *tcp, long addr, struct mmsghdr *mmsg)
+{
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+ if (current_wordsize == 4) {
+ struct mmsghdr32 mmsg32;
+
+ 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
+ if (umove(tcp, addr, mmsg) < 0)
+ return false;
+ 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)
+ addr += sizeof(struct mmsghdr32) * idx;
+ else
+#endif
+ addr += sizeof(*mmsg) * idx;
+ return extractmmsghdr0(tcp, addr, mmsg);
+}
+
static void
printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
{
@@ -450,40 +480,36 @@ dumpiov_in_msghdr(struct tcb *tcp, long addr)
dumpiov(tcp, msg.msg_iovlen, (long)msg.msg_iov);
}
+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", mmsg.msg_hdr.msg_iovlen, i);
+ dumpiov(tcp, mmsg.msg_hdr.msg_iovlen, (long)mmsg.msg_hdr.msg_iov);
+ }
+ }
+}
+
static void
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
+ if (extractmmsghdr(tcp, addr, idx, &mmsg))
{
- addr += sizeof(mmsg) * idx;
- if (umove(tcp, addr, &mmsg) < 0) {
- tprintf("%#lx", addr);
- return;
- }
+ 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
diff --git a/syscall.c b/syscall.c
index fa761a9..005a079 100644
--- a/syscall.c
+++ b/syscall.c
@@ -2501,6 +2501,10 @@ dumpio(struct tcb *tcp)
else if (func == sys_recvmsg)
dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
#endif
+#if HAVE_SENDMMSG
+ else if (func == sys_recvmmsg)
+ dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
+#endif
return;
}
if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
@@ -2515,6 +2519,10 @@ dumpio(struct tcb *tcp)
else if (func == sys_sendmsg)
dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
#endif
+#if HAVE_SENDMMSG
+ else if (func == sys_sendmmsg)
+ dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
+#endif
return;
}
}
--
1.9.3
More information about the Strace-devel
mailing list