summaryrefslogtreecommitdiff
path: root/regress/sys/dev/kcov/kcov.c
diff options
context:
space:
mode:
Diffstat (limited to 'regress/sys/dev/kcov/kcov.c')
-rw-r--r--regress/sys/dev/kcov/kcov.c133
1 files changed, 71 insertions, 62 deletions
diff --git a/regress/sys/dev/kcov/kcov.c b/regress/sys/dev/kcov/kcov.c
index 95bc221f8ec..87b3e6e17d1 100644
--- a/regress/sys/dev/kcov/kcov.c
+++ b/regress/sys/dev/kcov/kcov.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kcov.c,v 1.11 2019/05/14 20:48:45 anton Exp $ */
+/* $OpenBSD: kcov.c,v 1.12 2019/05/19 09:34:59 anton Exp $ */
/*
* Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
@@ -30,13 +30,19 @@
#include <string.h>
#include <unistd.h>
-static int test_close(int, int, unsigned long);
-static int test_coverage(int, int, unsigned long);
-static int test_dying(int, int, unsigned long);
-static int test_exec(int, int, unsigned long);
-static int test_fork(int, int, unsigned long);
-static int test_open(int, int, unsigned long);
-static int test_state(int, int, unsigned long);
+struct context {
+ int c_fd;
+ int c_mode;
+ unsigned long c_bufsize;
+};
+
+static int test_close(const struct context *);
+static int test_coverage(const struct context *);
+static int test_dying(const struct context *);
+static int test_exec(const struct context *);
+static int test_fork(const struct context *);
+static int test_open(const struct context *);
+static int test_state(const struct context *);
static int check_coverage(const unsigned long *, int, unsigned long, int);
static void do_syscall(void);
@@ -53,7 +59,7 @@ main(int argc, char *argv[])
{
struct {
const char *name;
- int (*fn)(int, int, unsigned long);
+ int (*fn)(const struct context *);
int coverage; /* test must produce coverage */
} tests[] = {
{ "close", test_close, 0 },
@@ -65,36 +71,38 @@ main(int argc, char *argv[])
{ "state", test_state, 1 },
{ NULL, NULL, 0 },
};
+ struct context ctx;
const char *errstr;
unsigned long *cover, frac;
- unsigned long bufsize = 256 << 10;
- int c, fd, i;
+ int c, i;
int error = 0;
- int mode = 0;
int prereq = 0;
int reexec = 0;
int verbose = 0;
self = argv[0];
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.c_bufsize = 256 << 10;
+
while ((c = getopt(argc, argv, "b:Em:pv")) != -1)
switch (c) {
case 'b':
frac = strtonum(optarg, 1, 100, &errstr);
if (frac == 0)
errx(1, "buffer size fraction %s", errstr);
- else if (frac > bufsize)
+ else if (frac > ctx.c_bufsize)
errx(1, "buffer size fraction too large");
- bufsize /= frac;
+ ctx.c_bufsize /= frac;
break;
case 'E':
reexec = 1;
break;
case 'm':
if (strcmp(optarg, "pc") == 0)
- mode = KCOV_MODE_TRACE_PC;
+ ctx.c_mode = KCOV_MODE_TRACE_PC;
else if (strcmp(optarg, "cmp") == 0)
- mode = KCOV_MODE_TRACE_CMP;
+ ctx.c_mode = KCOV_MODE_TRACE_CMP;
else
errx(1, "unknown mode %s", optarg);
break;
@@ -111,8 +119,8 @@ main(int argc, char *argv[])
argv += optind;
if (prereq) {
- fd = kcov_open();
- close(fd);
+ ctx.c_fd = kcov_open();
+ close(ctx.c_fd);
return 0;
}
@@ -121,7 +129,7 @@ main(int argc, char *argv[])
return 0;
}
- if (mode == 0 || argc != 1)
+ if (ctx.c_mode == 0 || argc != 1)
usage();
for (i = 0; tests[i].name != NULL; i++)
if (strcmp(argv[0], tests[i].name) == 0)
@@ -129,24 +137,24 @@ main(int argc, char *argv[])
if (tests[i].name == NULL)
errx(1, "%s: no such test", argv[0]);
- fd = kcov_open();
- if (ioctl(fd, KIOSETBUFSIZE, &bufsize) == -1)
+ ctx.c_fd = kcov_open();
+ if (ioctl(ctx.c_fd, KIOSETBUFSIZE, &ctx.c_bufsize) == -1)
err(1, "ioctl: KIOSETBUFSIZE");
- cover = mmap(NULL, bufsize * sizeof(unsigned long),
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ cover = mmap(NULL, ctx.c_bufsize * sizeof(unsigned long),
+ PROT_READ | PROT_WRITE, MAP_SHARED, ctx.c_fd, 0);
if (cover == MAP_FAILED)
err(1, "mmap");
*cover = 0;
- error = tests[i].fn(fd, mode, bufsize);
+ error = tests[i].fn(&ctx);
if (verbose)
- dump(cover, mode);
- if (check_coverage(cover, mode, bufsize, tests[i].coverage))
+ dump(cover, ctx.c_mode);
+ if (check_coverage(cover, ctx.c_mode, ctx.c_bufsize, tests[i].coverage))
error = 1;
- if (munmap(cover, bufsize * sizeof(unsigned long)) == -1)
+ if (munmap(cover, ctx.c_bufsize * sizeof(unsigned long)) == -1)
err(1, "munmap");
- close(fd);
+ close(ctx.c_fd);
return error;
}
@@ -178,7 +186,8 @@ check_coverage(const unsigned long *cover, int mode, unsigned long maxsize,
warnx("coverage not empty (count=%lu)\n", *cover);
return 1;
} else if (cover[0] >= maxsize) {
- warnx("coverage overflow (count=%lu, max=%lu)\n", *cover, maxsize);
+ warnx("coverage overflow (count=%lu, max=%lu)\n",
+ *cover, maxsize);
return 1;
}
@@ -251,7 +260,7 @@ kcov_disable(int fd)
* Close before mmap.
*/
static int
-test_close(int oldfd, int mode, unsigned long bufsize)
+test_close(const struct context *ctx)
{
int fd;
@@ -264,20 +273,20 @@ test_close(int oldfd, int mode, unsigned long bufsize)
* Coverage of current thread.
*/
static int
-test_coverage(int fd, int mode, unsigned long bufsize)
+test_coverage(const struct context *ctx)
{
- kcov_enable(fd, mode);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
do_syscall();
- kcov_disable(fd);
+ kcov_disable(ctx->c_fd);
return 0;
}
static void *
closer(void *arg)
{
- int fd = *((int *)arg);
+ const struct context *ctx = arg;
- close(fd);
+ close(ctx->c_fd);
return NULL;
}
@@ -285,19 +294,19 @@ closer(void *arg)
* Close kcov descriptor in another thread during tracing.
*/
static int
-test_dying(int fd, int mode, unsigned long bufsize)
+test_dying(const struct context *ctx)
{
pthread_t th;
int error;
- kcov_enable(fd, mode);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
- if ((error = pthread_create(&th, NULL, closer, &fd)))
+ if ((error = pthread_create(&th, NULL, closer, (void *)ctx)))
errc(1, error, "pthread_create");
if ((error = pthread_join(th, NULL)))
errc(1, error, "pthread_join");
- if (close(fd) == -1) {
+ if (close(ctx->c_fd) == -1) {
if (errno != EBADF)
err(1, "close");
} else {
@@ -312,7 +321,7 @@ test_dying(int fd, int mode, unsigned long bufsize)
* Coverage of thread after exec.
*/
static int
-test_exec(int fd, int mode, unsigned long bufsize)
+test_exec(const struct context *ctx)
{
pid_t pid;
int status;
@@ -321,7 +330,7 @@ test_exec(int fd, int mode, unsigned long bufsize)
if (pid == -1)
err(1, "fork");
if (pid == 0) {
- kcov_enable(fd, mode);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
execlp(self, self, "-E", NULL);
_exit(1);
}
@@ -337,8 +346,8 @@ test_exec(int fd, int mode, unsigned long bufsize)
}
/* Upon exit, the kcov descriptor must be reusable again. */
- kcov_enable(fd, mode);
- kcov_disable(fd);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
+ kcov_disable(ctx->c_fd);
return 0;
}
@@ -347,7 +356,7 @@ test_exec(int fd, int mode, unsigned long bufsize)
* Coverage of thread after fork.
*/
static int
-test_fork(int fd, int mode, unsigned long bufsize)
+test_fork(const struct context *ctx)
{
pid_t pid;
int status;
@@ -356,7 +365,7 @@ test_fork(int fd, int mode, unsigned long bufsize)
if (pid == -1)
err(1, "fork");
if (pid == 0) {
- kcov_enable(fd, mode);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
do_syscall();
_exit(0);
}
@@ -372,8 +381,8 @@ test_fork(int fd, int mode, unsigned long bufsize)
}
/* Upon exit, the kcov descriptor must be reusable again. */
- kcov_enable(fd, mode);
- kcov_disable(fd);
+ kcov_enable(ctx->c_fd, ctx->c_mode);
+ kcov_disable(ctx->c_fd);
return 0;
}
@@ -382,27 +391,27 @@ test_fork(int fd, int mode, unsigned long bufsize)
* Open /dev/kcov more than once.
*/
static int
-test_open(int oldfd, int mode, unsigned long bufsize)
+test_open(const struct context *ctx)
{
unsigned long *cover;
int fd;
int error = 0;
fd = kcov_open();
- if (ioctl(fd, KIOSETBUFSIZE, &bufsize) == -1)
+ if (ioctl(fd, KIOSETBUFSIZE, &ctx->c_bufsize) == -1)
err(1, "ioctl: KIOSETBUFSIZE");
- cover = mmap(NULL, bufsize * sizeof(unsigned long),
+ cover = mmap(NULL, ctx->c_bufsize * sizeof(unsigned long),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (cover == MAP_FAILED)
err(1, "mmap");
- kcov_enable(fd, mode);
+ kcov_enable(fd, ctx->c_mode);
do_syscall();
kcov_disable(fd);
- error = check_coverage(cover, mode, bufsize, 1);
+ error = check_coverage(cover, ctx->c_mode, ctx->c_bufsize, 1);
- if (munmap(cover, bufsize * sizeof(unsigned long)))
+ if (munmap(cover, ctx->c_bufsize * sizeof(unsigned long)))
err(1, "munmap");
close(fd);
@@ -413,35 +422,35 @@ test_open(int oldfd, int mode, unsigned long bufsize)
* State transitions.
*/
static int
-test_state(int fd, int mode, unsigned long bufsize)
+test_state(const struct context *ctx)
{
- if (ioctl(fd, KIOENABLE, &mode) == -1) {
+ if (ioctl(ctx->c_fd, KIOENABLE, &ctx->c_mode) == -1) {
warn("KIOSETBUFSIZE -> KIOENABLE");
return 1;
}
- if (ioctl(fd, KIODISABLE) == -1) {
+ if (ioctl(ctx->c_fd, KIODISABLE) == -1) {
warn("KIOENABLE -> KIODISABLE");
return 1;
}
- if (ioctl(fd, KIOSETBUFSIZE, 0) != -1) {
+ if (ioctl(ctx->c_fd, KIOSETBUFSIZE, 0) != -1) {
warnx("KIOSETBUFSIZE -> KIOSETBUFSIZE");
return 1;
}
- if (ioctl(fd, KIODISABLE) != -1) {
+ if (ioctl(ctx->c_fd, KIODISABLE) != -1) {
warnx("KIOSETBUFSIZE -> KIODISABLE");
return 1;
}
- kcov_enable(fd, mode);
- if (ioctl(fd, KIOENABLE, &mode) != -1) {
+ kcov_enable(ctx->c_fd, ctx->c_mode);
+ if (ioctl(ctx->c_fd, KIOENABLE, &ctx->c_mode) != -1) {
warnx("KIOENABLE -> KIOENABLE");
return 1;
}
- if (ioctl(fd, KIOSETBUFSIZE, 0) != -1) {
+ if (ioctl(ctx->c_fd, KIOSETBUFSIZE, 0) != -1) {
warnx("KIOENABLE -> KIOSETBUFSIZE");
return 1;
}
- kcov_disable(fd);
+ kcov_disable(ctx->c_fd);
return 0;
}