From c5c3f3aca9fd995fbf9990c8e061b8aef2bb6cf7 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 26 Feb 2014 11:57:18 -0600 Subject: [PATCH] Fix PR16636 by separating out preadv()/pwritev() testing. * tapset/linux/syscalls2.stp (syscall.preadv): The 'fd' and 'count' variables are 32-bits on the user side. Truncate them. (syscall.pwritev): Ditto. (syscall.readv): Ditto. (syscall.writev): Ditto. * testsuite/systemtap.syscall/readwrite.c: Move readv(), writev(), preadv(), pwritev() testing to their own files. * testsuite/systemtap.syscall/preadv.c: New test. * testsuite/systemtap.syscall/pwritev.c: Ditto. * testsuite/systemtap.syscall/readv.c: Ditto. * testsuite/systemtap.syscall/writev.c: Ditto. --- tapset/linux/syscalls2.stp | 45 +++++++------ testsuite/systemtap.syscall/preadv.c | 84 +++++++++++++++++++++++++ testsuite/systemtap.syscall/pwritev.c | 57 +++++++++++++++++ testsuite/systemtap.syscall/readv.c | 80 +++++++++++++++++++++++ testsuite/systemtap.syscall/readwrite.c | 38 +---------- testsuite/systemtap.syscall/writev.c | 54 ++++++++++++++++ 6 files changed, 302 insertions(+), 56 deletions(-) create mode 100644 testsuite/systemtap.syscall/preadv.c create mode 100644 testsuite/systemtap.syscall/pwritev.c create mode 100644 testsuite/systemtap.syscall/readv.c create mode 100644 testsuite/systemtap.syscall/writev.c diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index 5962cddea..cd60af1ba 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -568,21 +568,22 @@ probe syscall.preadv = __syscall.preadv ?, __syscall.compat_preadv ? } probe __syscall.preadv = kernel.function("sys_preadv") { - fd = $fd + fd = __int32($fd) vector_uaddr = $vec - count = $vlen + count = __int32($vlen) offset = ($pos_h << %{ BITS_PER_LONG %}) + $pos_l - argstr = sprintf("%d, %p, %d, 0x%x", $fd, $vec, $vlen, + argstr = sprintf("%d, %p, %d, 0x%x", __int32($fd), $vec, + __int32($vlen), ($pos_h << %{ BITS_PER_LONG %}) + $pos_l) } probe __syscall.compat_preadv = kernel.function("compat_sys_preadv") { - fd = $fd + fd = __int32($fd) vector_uaddr = $vec - count = $vlen + count = __int32($vlen) offset = ($pos_high << 32) + $pos_low - argstr = sprintf("%d, %p, %d, 0x%x", $fd, $vec, $vlen, - ($pos_high << 32) + $pos_low) + argstr = sprintf("%d, %p, %d, 0x%x", __int32($fd), $vec, + __int32($vlen), ($pos_high << 32) + $pos_low) } probe syscall.preadv.return = kernel.function("sys_preadv").return ?, kernel.function("compat_sys_preadv").return ? @@ -745,20 +746,22 @@ probe syscall.pwritev = __syscall.pwritev ?, __syscall.compat_pwritev ? } probe __syscall.pwritev = kernel.function("sys_pwritev").call { - fd = $fd + fd = __int32($fd) vector_uaddr = $vec - count = $vlen + count = __int32($vlen) offset = ($pos_h << %{ BITS_PER_LONG %}) + $pos_l - argstr = sprintf("%d, %p, %d, 0x%x", $fd, $vec, $vlen, + argstr = sprintf("%d, %p, %d, 0x%x", __int32($fd), $vec, + __int32($vlen), ($pos_h << %{ BITS_PER_LONG %}) + $pos_l) } probe __syscall.compat_pwritev = kernel.function("compat_sys_pwritev").call { - fd = $fd + fd = __int32($fd) vector_uaddr = $vec - count = $vlen + count = __int32($vlen) offset = ($pos_high << 32) + $pos_low - argstr = sprintf("%d, %p, %d, 0x%x", $fd, $vec, $vlen, + argstr = sprintf("%d, %p, %d, 0x%x", __int32($fd), $vec, + __int32($vlen), ($pos_high << 32) + $pos_low) } probe syscall.pwritev.return = kernel.function("sys_pwritev").return ?, @@ -911,9 +914,11 @@ probe syscall.readv = kernel.function("compat_sys_readv").call ?, { name = "readv" vector_uaddr = $vec - count = $vlen - fd = $fd - argstr = sprintf("%d, %p, %d", $fd, $vec, $vlen) + count = __int32($vlen) + # Although the kernel gets an unsigned long fd, on the + # user-side it is a signed int. Fix this. + fd = __int32($fd) + argstr = sprintf("%d, %p, %d", __int32($fd), $vec, __int32($vlen)) } probe syscall.readv.return = kernel.function("compat_sys_readv").return ?, kernel.function("sys_readv").return @@ -3951,9 +3956,11 @@ probe syscall.writev = kernel.function("compat_sys_writev").call ?, { name = "writev" vector_uaddr = $vec - count = $vlen - fd = $fd - argstr = sprintf("%d, %p, %d", $fd, $vec, $vlen) + count = __int32($vlen) + # Although the kernel gets an unsigned long fd, on the + # user-side it is a signed int. Fix this. + fd = __int32($fd) + argstr = sprintf("%d, %p, %d", __int32($fd), $vec, __int32($vlen)) } probe syscall.writev.return = kernel.function("compat_sys_writev").return ?, kernel.function("sys_writev").return diff --git a/testsuite/systemtap.syscall/preadv.c b/testsuite/systemtap.syscall/preadv.c new file mode 100644 index 000000000..cea71a108 --- /dev/null +++ b/testsuite/systemtap.syscall/preadv.c @@ -0,0 +1,84 @@ +/* COVERAGE: preadv */ +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd; + struct iovec rd_iovec[3]; + char buf[64]; + + fd = open("foobar1", O_WRONLY|O_CREAT, 0666); + //staptest// open ("foobar1", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?, 0666) = NNNN + memset(buf, (int)'B', sizeof(buf)); + write(fd, buf, sizeof(buf)); + //staptest// write (NNNN, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"..., 64) = 64 + + close(fd); + //staptest// close (NNNN) = 0 + + fd = open("foobar1", O_RDONLY); + //staptest// open ("foobar1", O_RDONLY[[[[.O_LARGEFILE]]]]?) = NNNN + + rd_iovec[0].iov_base = buf; + rd_iovec[0].iov_len = sizeof(buf); + rd_iovec[1].iov_base = NULL; + rd_iovec[1].iov_len = 0; + rd_iovec[2].iov_base = NULL; + rd_iovec[2].iov_len = 0; + + preadv(fd, rd_iovec, 0, 0); + //staptest// preadv (NNNN, XXXX, 0, 0x0) = 0 + + memset(buf, 0x0, sizeof(buf)); + preadv(fd, rd_iovec, 3, 0); + //staptest// preadv (NNNN, XXXX, 3, 0x0) = 64 + + memset(buf, 0x0, sizeof(buf)); + preadv(fd, rd_iovec, 3, 32); + //staptest// preadv (NNNN, XXXX, 3, 0x20) = 32 + + rd_iovec[0].iov_len = -1; + preadv(fd, rd_iovec, 1, 0); + //staptest// preadv (NNNN, XXXX, 1, 0x0) = -NNNN (EINVAL) + + rd_iovec[0].iov_base = (char *)-1; + rd_iovec[0].iov_len = sizeof(buf); + preadv(fd, rd_iovec, 1, 0); + // On 64-bit platforms, we get a EFAULT. On 32-on-64 bits, we + // typically get a 0. + //staptest// preadv (NNNN, XXXX, 1, 0x0) = [[[[0!!!!-NNNN (EFAULT)]]]] + + rd_iovec[0].iov_base = buf; + rd_iovec[0].iov_len = sizeof(buf); + preadv(-1, rd_iovec, 1, 0); + //staptest// preadv (-1, XXXX, 1, 0x0) = -NNNN (EBADF) + + preadv(fd, rd_iovec, -1, 0); + //staptest// preadv (NNNN, XXXX, -1, 0x0) = -NNNN (EINVAL) + + close (fd); + //staptest// close (NNNN) = 0 + + mkdir("dir1", S_IREAD|S_IWRITE|S_IEXEC); + //staptest// mkdir ("dir1", 0700) = 0 + + fd = open("dir1", O_RDONLY); + //staptest// open ("dir1", O_RDONLY) = NNNN + + preadv(fd, rd_iovec, 1, 0); + //staptest// preadv (NNNN, XXXX, 1, 0x0) = -NNNN (EISDIR) + + close (fd); + //staptest// close (NNNN) = 0 + + return 0; +} diff --git a/testsuite/systemtap.syscall/pwritev.c b/testsuite/systemtap.syscall/pwritev.c new file mode 100644 index 000000000..c44d55151 --- /dev/null +++ b/testsuite/systemtap.syscall/pwritev.c @@ -0,0 +1,57 @@ +/* COVERAGE: pwritev */ +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd; + struct iovec wr_iovec[3]; + char buf[64]; + + fd = open("foobar1", O_WRONLY|O_CREAT, 0666); + //staptest// open ("foobar1", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?, 0666) = NNNN + + memset(buf, (int)'B', sizeof(buf)); + wr_iovec[0].iov_base = buf; + wr_iovec[0].iov_len = -1; + wr_iovec[1].iov_base = NULL; + wr_iovec[1].iov_len = 0; + wr_iovec[2].iov_base = NULL; + wr_iovec[2].iov_len = 0; + pwritev(fd, wr_iovec, 1, 0); + //staptest// pwritev (NNNN, XXXX, 1, 0x0) = -NNNN (EINVAL) + + pwritev(-1, wr_iovec, 1, 0); + //staptest// pwritev (-1, XXXX, 1, 0x0) = -NNNN (EBADF) + + pwritev(fd, wr_iovec, -1, 0); + //staptest// pwritev (NNNN, XXXX, -1, 0x0) = -NNNN (EINVAL) + + pwritev(fd, wr_iovec, 0, 0); + //staptest// pwritev (NNNN, XXXX, 0, 0x0) = 0 + + wr_iovec[0].iov_base = buf; + wr_iovec[0].iov_len = sizeof(buf); + wr_iovec[1].iov_base = buf; + wr_iovec[1].iov_len = 0; + wr_iovec[2].iov_base = NULL; + wr_iovec[2].iov_len = 0; + pwritev(fd, wr_iovec, 3, 0); + //staptest// pwritev (NNNN, XXXX, 3, 0x0) = 64 + + pwritev(fd, wr_iovec, 3, 64); + //staptest// pwritev (NNNN, XXXX, 3, 0x40) = 64 + + close (fd); + //staptest// close (NNNN) = 0 + + return 0; +} diff --git a/testsuite/systemtap.syscall/readv.c b/testsuite/systemtap.syscall/readv.c new file mode 100644 index 000000000..36a6278fb --- /dev/null +++ b/testsuite/systemtap.syscall/readv.c @@ -0,0 +1,80 @@ +/* COVERAGE: readv */ +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd; + struct iovec rd_iovec[3]; + char buf[64]; + + fd = open("foobar1", O_WRONLY|O_CREAT, 0666); + //staptest// open ("foobar1", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?, 0666) = NNNN + memset(buf, (int)'B', sizeof(buf)); + write(fd, buf, sizeof(buf)); + //staptest// write (NNNN, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"..., 64) = 64 + + close(fd); + //staptest// close (NNNN) = 0 + + fd = open("foobar1", O_RDONLY); + //staptest// open ("foobar1", O_RDONLY[[[[.O_LARGEFILE]]]]?) = NNNN + + rd_iovec[0].iov_base = buf; + rd_iovec[0].iov_len = sizeof(buf); + rd_iovec[1].iov_base = NULL; + rd_iovec[1].iov_len = 0; + rd_iovec[2].iov_base = NULL; + rd_iovec[2].iov_len = 0; + + readv(fd, rd_iovec, 0); + //staptest// readv (NNNN, XXXX, 0) = 0 + + memset(buf, 0x0, sizeof(buf)); + readv(fd, rd_iovec, 3); + //staptest// readv (NNNN, XXXX, 3) = 64 + + rd_iovec[0].iov_len = -1; + readv(fd, rd_iovec, 1); + //staptest// readv (NNNN, XXXX, 1) = -NNNN (EINVAL) + + rd_iovec[0].iov_base = (char *)-1; + rd_iovec[0].iov_len = sizeof(buf); + readv(fd, rd_iovec, 1); + // On 64-bit platforms, we get a EFAULT. On 32-on-64 bits, we + // typically get a 0. + //staptest// readv (NNNN, XXXX, 1) = [[[[0!!!!-NNNN (EFAULT)]]]] + + rd_iovec[0].iov_base = buf; + rd_iovec[0].iov_len = sizeof(buf); + readv(-1, rd_iovec, 1); + //staptest// readv (-1, XXXX, 1) = -NNNN (EBADF) + + readv(fd, rd_iovec, -1); + //staptest// readv (NNNN, XXXX, -1) = -NNNN (EINVAL) + + close (fd); + //staptest// close (NNNN) = 0 + + mkdir("dir1", S_IREAD|S_IWRITE|S_IEXEC); + //staptest// mkdir ("dir1", 0700) = 0 + + fd = open("dir1", O_RDONLY); + //staptest// open ("dir1", O_RDONLY) = NNNN + + readv(fd, rd_iovec, 1); + //staptest// readv (NNNN, XXXX, 1) = -NNNN (EISDIR) + + close (fd); + //staptest// close (NNNN) = 0 + + return 0; +} diff --git a/testsuite/systemtap.syscall/readwrite.c b/testsuite/systemtap.syscall/readwrite.c index 181cbb659..cd3878a30 100644 --- a/testsuite/systemtap.syscall/readwrite.c +++ b/testsuite/systemtap.syscall/readwrite.c @@ -1,4 +1,4 @@ -/* COVERAGE: read write readv preadv writev pwritev lseek llseek */ +/* COVERAGE: read write lseek llseek */ #define _BSD_SOURCE #define _DEFAULT_SOURCE #include @@ -16,17 +16,9 @@ int main() { int fd; - struct iovec v[3], x[3]; loff_t res; char buf[64], buf1[32], buf2[32], buf3[32]; - v[0].iov_base = STRING1; - v[0].iov_len = sizeof(STRING1); - v[1].iov_base = STRING2; - v[1].iov_len = sizeof(STRING2); - v[2].iov_base = STRING3; - v[2].iov_len = sizeof(STRING3); - fd = open("foobar1",O_WRONLY|O_CREAT, 0666); //staptest// open ("foobar1", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?, 0666) = NNNN @@ -39,17 +31,6 @@ int main() pwrite(fd,"Hello Again",11,12); //staptest// pwrite (NNNN, "Hello Again", 11, 12) = 11 - writev(fd, v, 3); - //staptest// writev (NNNN, XXXX, 3) = 15 - -#ifdef SYS_pwritev - pwritev(fd, v, 3, 0); - //staptest// pwritev (NNNN, XXXX, 3, 0x0) = 15 - - pwritev(fd, v, 3, 0x100); - //staptest// pwritev (NNNN, XXXX, 3, 0x100) = 15 -#endif - lseek(fd, 0, SEEK_SET); //staptest// lseek (NNNN, 0, SEEK_SET) = 0 @@ -88,23 +69,6 @@ int main() pread(fd, buf, 11, 10); //staptest// pread (NNNN, XXXX, 11, 10) = 11 - x[0].iov_base = buf1; - x[0].iov_len = sizeof(STRING1); - x[1].iov_base = buf2; - x[1].iov_len = sizeof(STRING2); - x[2].iov_base = buf3; - x[2].iov_len = sizeof(STRING3); - readv(fd, x, 3); - //staptest// readv (NNNN, XXXX, 3) = 15 - -#ifdef SYS_preadv - preadv(fd, x, 3, 0); - //staptest// preadv (NNNN, XXXX, 3, 0x0) = 15 - - preadv(fd, x, 3, 0x100); - //staptest// preadv (NNNN, XXXX, 3, 0x100) = 15 -#endif - close (fd); //staptest// close (NNNN) = 0 diff --git a/testsuite/systemtap.syscall/writev.c b/testsuite/systemtap.syscall/writev.c new file mode 100644 index 000000000..aeafa4911 --- /dev/null +++ b/testsuite/systemtap.syscall/writev.c @@ -0,0 +1,54 @@ +/* COVERAGE: writev */ +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd; + struct iovec wr_iovec[3]; + char buf[64]; + + fd = open("foobar1", O_WRONLY|O_CREAT, 0666); + //staptest// open ("foobar1", O_WRONLY|O_CREAT[[[[.O_LARGEFILE]]]]?, 0666) = NNNN + + memset(buf, (int)'B', sizeof(buf)); + wr_iovec[0].iov_base = buf; + wr_iovec[0].iov_len = -1; + wr_iovec[1].iov_base = NULL; + wr_iovec[1].iov_len = 0; + wr_iovec[2].iov_base = NULL; + wr_iovec[2].iov_len = 0; + writev(fd, wr_iovec, 1); + //staptest// writev (NNNN, XXXX, 1) = -NNNN (EINVAL) + + writev(-1, wr_iovec, 1); + //staptest// writev (-1, XXXX, 1) = -NNNN (EBADF) + + writev(fd, wr_iovec, -1); + //staptest// writev (NNNN, XXXX, -1) = -NNNN (EINVAL) + + writev(fd, wr_iovec, 0); + //staptest// writev (NNNN, XXXX, 0) = 0 + + wr_iovec[0].iov_base = buf; + wr_iovec[0].iov_len = sizeof(buf); + wr_iovec[1].iov_base = buf; + wr_iovec[1].iov_len = 0; + wr_iovec[2].iov_base = NULL; + wr_iovec[2].iov_len = 0; + writev(fd, wr_iovec, 3); + //staptest// writev (NNNN, XXXX, 3) = 64 + + close (fd); + //staptest// close (NNNN) = 0 + + return 0; +} -- 2.43.5