[RFC PATCH] Test for syscall templates
Yury Norov
ynorov@caviumnetworks.com
Sat Feb 11 14:47:00 GMT 2017
On Fri, Feb 10, 2017 at 09:10:03AM -0500, Zack Weinberg wrote:
> On Fri, Feb 10, 2017 at 8:27 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> > On Fri, Feb 10, 2017 at 07:51:07AM -0500, Zack Weinberg wrote:
> >> On Fri, Feb 10, 2017 at 5:10 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> >> >
> >> > This is RFC because I'm not sure this is right way to check the macro
> >>
> >> The way to make this a better test, and ensure you're not just testing
> >> one of several possible implementations of the
> >> trap-to-kernel-then-set-errno sequence, is to apply the same test to
> >> _as many syscalls as practical_.
> >
> > So I only tried to test error path of syscall template. If you think
> > that the correct way to do it is to call each syscall that may fail
> > in each possible scenario - then I think glibc don't need the test
> > like that, and we'd run LTP to find bugs of that sort - like I did in
> > this case.
>
> You asked how to make the test better. I told you how I think you
> could make the test better.
>
> I realize I'm asking for some extra work, but it should not take more
> than a half hour and it really will be a better test this way.
>
> (I _do_ think glibc should have a test like this. It does not require
> elaborate setup, and the more bugs we can catch _during development_,
> rather than months after the fact when someone thinks to run LTP, the
> better.)
>
> zw
OK. Below is what I have. This is not the glibc test but standalone
application. If I do what you mean, I will finish the syscall list
(I take it from sysdeps/unix/syscalls.list), and send it as glibc test
for POSIX syscalls. IIUC we need similar test for linux syscalls in
sysdeps/unix/sysv/linux/syscalls.list
Surprisingly, some syscalls cause segfaults on aarch64/lp64, which is
presumably wrong.
I didn't analyze it yet, and didn't finish the test. Just asking if I
understand you right.
Yury
--
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <sys/mman.h>
#include <unistd.h>
#define test_wrp(err, test_syscall, params...) do { \
errno = 0xdead; \
int ret = test_syscall(params); \
if (ret != -1) \
printf("Syscall '" #test_syscall \
"' didn't fail as expected\n"); \
else if (errno == 0xdead) \
printf("Syscall'" #test_syscall \
"' didn't update errno\n"); \
else if (errno != err) { \
printf("Syscall'" #test_syscall "':\n"); \
printf("errno is: %d (%s)\nexpected: %d (%s)\n", \
errno, strerror (errno), err, strerror (err)); \
} \
else \
break; \
return -1; \
} while (0)
int main(int argc, char *argv[])
{
test_wrp(EBADF, write, -1, "Hello", sizeof("Hello") );
test_wrp(EFAULT, access, (void *) -1, 0);
test_wrp(EFAULT, acct, (void *) -1);
test_wrp(EBADF, bind, -1, (void *) -1, 0);
test_wrp(EFAULT, chdir, (void *) -1);
test_wrp(EFAULT, chmod, (void *) -1, 0);
test_wrp(EBADF, close, -1);
test_wrp(EBADF, connect, -1, (void *) -1, -1);
test_wrp(EBADF, dup, -1);
test_wrp(EBADF, fcntl, -1, 0);
test_wrp(EBADF, fstatfs, -1, (void *) -1);
test_wrp(EBADF, fsync, -1);
test_wrp(EBADF, ftruncate, -1, 0);
//test_wrp(EFAULT, getdomainname, (void *) -1, 1); //segfault
test_wrp(EINVAL, getgroups, -1, (void *) -1);
//test_wrp(EFAULT, gethostname, -1, (void *) -1); //segfault
//test_wrp(EFAULT, gettimeofday, (void *) -1, (void *) -1); //segfault
test_wrp(EBADF, ioctl, -1, 0);
test_wrp(EFAULT, link, (void *) -1, (void *) -1);
test_wrp(EBADF, listen, -1, -1);
test_wrp(EBADF, lseek, -1, 0, 0);
test_wrp(EINVAL, madvise, (void *) -1, 0, 0);
test_wrp(EFAULT, mkdir, (void *) -1, 0);
//test_wrp(EBADF, mmap, (void *) -1, 0, 0, 0, -1, 0); //compiler warning
test_wrp(EINVAL, mprotect, (void *) -1, 0, 0);
test_wrp(EINVAL, msync, (void *) -1, 0, 0);
test_wrp(EINVAL, munmap, (void *) -1, 0);
test_wrp(EFAULT, open, (void *) -1, 0);
test_wrp(EBADF, read, -1, (void *) -1, 0);
test_wrp(EINVAL, readlink, (void *) -1, (void *) -1, 0);
test_wrp(EBADF, readv, -1, (void *) -1, 1);
//test_wrp(EFAULT, recv, -1, (void *) -1, 1, 0); lp64 and ilp32 //different errors
test_wrp(EBADF, recvmsg, -1, (void *) -1, 0);
test_wrp(EFAULT, rename, (void *) -1, (void *) -1);
test_wrp(EFAULT, rmdir, (void *) -1);
//test_wrp(EINVAL, select, -1, (void *) -1, (void *) -1, (void *) -1, (void *) -1); //segfault
return 0;
}
More information about the Libc-alpha
mailing list