[BACK]Return to t_kcov.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / tests / modules

Annotation of src/tests/modules/t_kcov.c, Revision 1.10

1.1       kamil       1: /*
                      2:  * SPDX-License-Identifier: BSD-2-Clause
                      3:  *
                      4:  * Copyright (c) 2018, 2019 Andrew Turner
                      5:  *
                      6:  * This software was developed by SRI International and the University of
                      7:  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
                      8:  * ("CTSRD"), as part of the DARPA CRASH research programme.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31: #include <sys/cdefs.h>
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/ioctl.h>
                     35: #include <sys/kcov.h>
                     36: #include <sys/mman.h>
                     37:
1.5       kamil      38: #include <errno.h>
1.1       kamil      39: #include <fcntl.h>
                     40: #include <pthread.h>
                     41: #include <semaphore.h>
1.7       kamil      42: #include <unistd.h>
1.1       kamil      43:
                     44: #include <atf-c.h>
                     45:
                     46: #define PAGE_SIZE sysconf(_SC_PAGESIZE)
                     47:
                     48: static int
                     49: open_kcov(void)
                     50: {
                     51:        int fd;
                     52:
                     53:        fd = open("/dev/kcov", O_RDWR);
                     54:        if (fd == -1)
                     55:                atf_tc_skip("Failed to open /dev/kcov");
                     56:
                     57:        return fd;
                     58: }
                     59:
1.8       kamil      60: static int
                     61: pick_unassigned_fd(int greater_than_fd)
                     62: {
                     63:        int fd2;
                     64:
                     65:        fd2 = greater_than_fd;
                     66:        do {
                     67:                ++fd2;
                     68:        } while (fcntl(fd2, F_GETFL) != -1 || errno != EBADF);
                     69:
                     70:        return fd2;
                     71: }
                     72:
                     73: ATF_TC_WITHOUT_HEAD(kcov_dup2);
                     74: ATF_TC_BODY(kcov_dup2, tc)
                     75: {
                     76:        int fd1, fd2;
                     77:        fd1 = open_kcov();
                     78:
                     79:        fd2 = pick_unassigned_fd(fd1);
                     80:
                     81:        /* Test the dup2(2) trick used by syzkaller */
                     82:        ATF_REQUIRE_EQ(dup2(fd1, fd2), fd2);
                     83:
                     84:        close(fd1);
                     85:        close(fd2);
                     86: }
                     87:
1.5       kamil      88: ATF_TC_WITHOUT_HEAD(kcov_multiopen);
                     89: ATF_TC_BODY(kcov_multiopen, tc)
                     90: {
                     91:        int fd1, fd2;
                     92:        fd1 = open_kcov();
                     93:
                     94:        fd2 = open("/dev/kcov", O_RDWR);
                     95:        ATF_REQUIRE(fd2 != -1);
                     96:
                     97:        close(fd1);
                     98:        close(fd2);
                     99: }
                    100:
                    101: ATF_TC_WITHOUT_HEAD(kcov_open_close_open);
                    102: ATF_TC_BODY(kcov_open_close_open, tc)
                    103: {
                    104:        int fd;
                    105:
                    106:        fd = open_kcov();
                    107:        close(fd);
                    108:        fd = open("/dev/kcov", O_RDWR);
                    109:        ATF_REQUIRE(fd != -1);
                    110:
                    111:        close(fd);
                    112: }
                    113:
1.1       kamil     114: ATF_TC_WITHOUT_HEAD(kcov_bufsize);
                    115: ATF_TC_BODY(kcov_bufsize, tc)
                    116: {
                    117:        int fd;
1.5       kamil     118:        uint64_t size;
1.1       kamil     119:        fd = open_kcov();
                    120:
                    121:        size = 0;
                    122:        ATF_CHECK(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == -1);
                    123:        size = 2;
                    124:        ATF_CHECK(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0);
                    125:
                    126:        close(fd);
                    127: }
                    128:
                    129: ATF_TC_WITHOUT_HEAD(kcov_mmap);
                    130: ATF_TC_BODY(kcov_mmap, tc)
                    131: {
                    132:        void *data;
                    133:        int fd;
1.5       kamil     134:        uint64_t size = 2 * PAGE_SIZE / KCOV_ENTRY_SIZE;
1.1       kamil     135:
                    136:        fd = open_kcov();
                    137:
                    138:        ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                    139:            fd, 0) == MAP_FAILED);
                    140:
                    141:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0);
                    142:
                    143:        ATF_REQUIRE((data = mmap(NULL, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE,
                    144:            MAP_SHARED, fd, 0)) != MAP_FAILED);
                    145:
                    146:        munmap(data, 2 * PAGE_SIZE);
                    147:
                    148:        close(fd);
                    149: }
                    150:
                    151: /* This shouldn't panic */
                    152: ATF_TC_WITHOUT_HEAD(kcov_mmap_no_munmap);
                    153: ATF_TC_BODY(kcov_mmap_no_munmap, tc)
                    154: {
                    155:        int fd;
1.5       kamil     156:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.1       kamil     157:
                    158:        fd = open_kcov();
                    159:
                    160:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
                    161:
                    162:        ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                    163:            fd, 0) != MAP_FAILED);
                    164:
                    165:        close(fd);
                    166: }
                    167:
                    168: ATF_TC_WITHOUT_HEAD(kcov_mmap_no_munmap_no_close);
                    169: ATF_TC_BODY(kcov_mmap_no_munmap_no_close, tc)
                    170: {
                    171:        int fd;
1.5       kamil     172:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.1       kamil     173:
                    174:        fd = open_kcov();
                    175:
                    176:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
                    177:
                    178:        ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                    179:            fd, 0) != MAP_FAILED);
                    180: }
                    181:
                    182: static sem_t sem1, sem2;
                    183:
                    184: static void *
                    185: kcov_mmap_enable_thread(void *data)
                    186: {
                    187:        int fd;
1.5       kamil     188:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.7       kamil     189:        int mode;
1.1       kamil     190:
                    191:        fd = open_kcov();
                    192:        *(int *)data = fd;
                    193:
                    194:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
                    195:        ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                    196:            fd, 0) != MAP_FAILED);
1.7       kamil     197:        mode = KCOV_MODE_NONE;
                    198:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
1.1       kamil     199:
                    200:        sem_post(&sem1);
                    201:        sem_wait(&sem2);
                    202:
                    203:        return NULL;
                    204: }
                    205:
                    206: ATF_TC_WITHOUT_HEAD(kcov_mmap_enable_thread_close);
                    207: ATF_TC_BODY(kcov_mmap_enable_thread_close, tc)
                    208: {
                    209:        pthread_t thread;
                    210:        int fd;
                    211:
                    212:        sem_init(&sem1, 0, 0);
                    213:        sem_init(&sem2, 0, 0);
                    214:        pthread_create(&thread, NULL,
                    215:            kcov_mmap_enable_thread, &fd);
                    216:        sem_wait(&sem1);
                    217:        close(fd);
                    218:        sem_post(&sem2);
                    219:        pthread_join(thread, NULL);
                    220: }
                    221:
                    222: ATF_TC_WITHOUT_HEAD(kcov_enable);
                    223: ATF_TC_BODY(kcov_enable, tc)
                    224: {
                    225:        int fd;
1.5       kamil     226:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.7       kamil     227:        int mode;
1.1       kamil     228:
                    229:        fd = open_kcov();
                    230:
1.7       kamil     231:        mode = KCOV_MODE_NONE;
                    232:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1);
1.1       kamil     233:
                    234:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
                    235:
                    236:        /* We need to enable before disable */
                    237:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1);
                    238:
                    239:        /* Check enabling works only with a valid trace method */
1.7       kamil     240:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
                    241:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1);
1.1       kamil     242:
                    243:        /* Disable should only be called once */
                    244:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
                    245:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1);
                    246:
1.8       kamil     247:        /* Re-enabling and changing mode should also work */
1.7       kamil     248:        mode = KCOV_MODE_NONE;
                    249:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
                    250:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
                    251:        mode = KCOV_MODE_TRACE_PC;
                    252:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
                    253:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
                    254:        mode = KCOV_MODE_TRACE_CMP;
                    255:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
1.1       kamil     256:        ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
                    257:
                    258:        close(fd);
                    259: }
                    260:
                    261: ATF_TC_WITHOUT_HEAD(kcov_enable_no_disable);
                    262: ATF_TC_BODY(kcov_enable_no_disable, tc)
                    263: {
                    264:        int fd;
1.5       kamil     265:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.7       kamil     266:        int mode;
1.1       kamil     267:
                    268:        fd = open_kcov();
                    269:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
1.7       kamil     270:        mode = KCOV_MODE_NONE;
                    271:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
1.1       kamil     272:        close(fd);
                    273: }
                    274:
                    275: ATF_TC_WITHOUT_HEAD(kcov_enable_no_disable_no_close);
                    276: ATF_TC_BODY(kcov_enable_no_disable_no_close, tc)
                    277: {
                    278:        int fd;
1.5       kamil     279:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.7       kamil     280:        int mode;
1.1       kamil     281:
                    282:        fd = open_kcov();
                    283:        ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
1.7       kamil     284:        mode = KCOV_MODE_NONE;
                    285:        ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
1.1       kamil     286: }
                    287:
                    288: static void *
1.8       kamil     289: common_head_raw(bool fd_dup, int *fdp)
1.1       kamil     290: {
                    291:        void *data;
1.8       kamil     292:        int fd, fd2;
1.5       kamil     293:        uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
1.1       kamil     294:
                    295:        fd = open_kcov();
                    296:
1.8       kamil     297:        /* Test the dup2(2) trick used by syzkaller */
                    298:        if (fd_dup) {
                    299:                fd2 = pick_unassigned_fd(fd);
                    300:                ATF_REQUIRE_EQ(dup2(fd, fd2), fd2);
                    301:                close(fd);
                    302:                fd = fd2;
                    303:        }
                    304:
1.1       kamil     305:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0,
                    306:            "Unable to set the kcov buffer size");
                    307:
                    308:        data = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
                    309:        ATF_REQUIRE_MSG(data != MAP_FAILED, "Unable to mmap the kcov buffer");
                    310:
                    311:        *fdp = fd;
                    312:        return data;
                    313: }
                    314:
1.8       kamil     315: static void *
                    316: common_head(int *fdp)
                    317: {
                    318:
                    319:        return common_head_raw(false, fdp);
                    320: }
                    321:
1.1       kamil     322: static void
                    323: common_tail(int fd, kcov_int_t *data)
                    324: {
                    325:
                    326:        ATF_REQUIRE_MSG(munmap(__UNVOLATILE(data), PAGE_SIZE) == 0,
                    327:            "Unable to unmap the kcov buffer");
                    328:
                    329:        close(fd);
                    330: }
                    331:
1.7       kamil     332: static void
1.8       kamil     333: kcov_basic(bool fd_dup, int mode)
1.1       kamil     334: {
                    335:        kcov_int_t *buf;
                    336:        int fd;
                    337:
1.8       kamil     338:        buf = common_head_raw(fd_dup, &fd);
1.7       kamil     339:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
1.1       kamil     340:            "Unable to enable kcov ");
                    341:
1.10    ! kamil     342:        buf[0] = 0;
1.1       kamil     343:
1.7       kamil     344:        sleep(0); /* XXX: Is it enough for all trace types? */
1.10    ! kamil     345:        ATF_REQUIRE_MSG(buf[0] != 0, "No records found");
1.1       kamil     346:
                    347:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
                    348:            "Unable to disable kcov");
                    349:
                    350:        common_tail(fd, buf);
                    351: }
                    352:
1.7       kamil     353: ATF_TC_WITHOUT_HEAD(kcov_basic_pc);
                    354: ATF_TC_BODY(kcov_basic_pc, tc)
                    355: {
                    356:
1.8       kamil     357:        kcov_basic(false, KCOV_MODE_TRACE_PC);
1.7       kamil     358: }
                    359:
                    360: ATF_TC_WITHOUT_HEAD(kcov_basic_cmp);
                    361: ATF_TC_BODY(kcov_basic_cmp, tc)
                    362: {
                    363:
                    364:        atf_tc_skip("XXX: GCC8 needed");
                    365:
1.8       kamil     366:        kcov_basic(false, KCOV_MODE_TRACE_CMP);
                    367: }
                    368:
                    369: ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_pc);
                    370: ATF_TC_BODY(kcov_basic_dup2_pc, tc)
                    371: {
                    372:
                    373:        kcov_basic(true, KCOV_MODE_TRACE_PC);
                    374: }
                    375:
                    376: ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_cmp);
                    377: ATF_TC_BODY(kcov_basic_dup2_cmp, tc)
                    378: {
                    379:
                    380:        atf_tc_skip("XXX: GCC8 needed");
                    381:
                    382:        kcov_basic(true, KCOV_MODE_TRACE_CMP);
1.7       kamil     383: }
                    384:
1.5       kamil     385: ATF_TC_WITHOUT_HEAD(kcov_multienable_on_the_same_thread);
                    386: ATF_TC_BODY(kcov_multienable_on_the_same_thread, tc)
                    387: {
                    388:        kcov_int_t *buf1, *buf2;
                    389:        int fd1, fd2;
1.7       kamil     390:        int mode;
1.5       kamil     391:
                    392:        buf1 = common_head(&fd1);
                    393:        buf2 = common_head(&fd2);
1.7       kamil     394:        mode = KCOV_MODE_NONE;
                    395:        ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_ENABLE, &mode) == 0,
1.5       kamil     396:            "Unable to enable kcov");
1.7       kamil     397:        ATF_REQUIRE_ERRNO(EBUSY, ioctl(fd2, KCOV_IOC_ENABLE, &mode) != 0);
1.5       kamil     398:
                    399:        ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_DISABLE) == 0,
                    400:            "Unable to disable kcov");
                    401:
                    402:        common_tail(fd1, buf1);
                    403:        common_tail(fd2, buf2);
                    404: }
                    405:
                    406: static void *
                    407: thread_buffer_access_test_helper(void *ptr)
                    408: {
                    409:        kcov_int_t *buf = ptr;
                    410:
                    411:        /* Test mapped buffer access from a custom thread */
1.10    ! kamil     412:        buf[0] = buf[0];
1.5       kamil     413:
                    414:        return NULL;
                    415: }
                    416:
                    417: ATF_TC_WITHOUT_HEAD(kcov_buffer_access_from_custom_thread);
                    418: ATF_TC_BODY(kcov_buffer_access_from_custom_thread, tc)
                    419: {
                    420:        pthread_t thread;
                    421:        kcov_int_t *buf;
                    422:        int fd;
1.7       kamil     423:        int mode;
1.5       kamil     424:
                    425:        buf = common_head(&fd);
                    426:
1.7       kamil     427:        mode = KCOV_MODE_TRACE_PC;
                    428:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
1.5       kamil     429:            "Unable to enable kcov ");
                    430:
                    431:        pthread_create(&thread, NULL, thread_buffer_access_test_helper,
                    432:            __UNVOLATILE(buf));
                    433:        pthread_join(thread, NULL);
                    434:
                    435:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
                    436:            "Unable to disable kcov");
                    437:
                    438:        common_tail(fd, buf);
                    439: }
                    440:
1.1       kamil     441: static void *
                    442: thread_test_helper(void *ptr)
                    443: {
1.5       kamil     444:        volatile int i;
1.1       kamil     445:
1.5       kamil     446:        /* It does not matter what operation is in action. */
                    447:        for (i = 0; i < 1000; i++) {
                    448:                if (getpid() == 0)
                    449:                        break;
                    450:        }
1.1       kamil     451:
                    452:        return NULL;
                    453: }
                    454:
                    455: ATF_TC_WITHOUT_HEAD(kcov_thread);
                    456: ATF_TC_BODY(kcov_thread, tc)
                    457: {
                    458:        pthread_t thread;
                    459:        kcov_int_t *buf;
                    460:        int fd;
1.7       kamil     461:        int mode;
1.5       kamil     462:        volatile int i;
1.1       kamil     463:
                    464:        buf = common_head(&fd);
                    465:
1.7       kamil     466:        mode = KCOV_MODE_TRACE_PC;
                    467:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
1.1       kamil     468:            "Unable to enable kcov ");
                    469:
1.5       kamil     470:        /* The thread does something, does not matter what exactly. */
1.1       kamil     471:        pthread_create(&thread, NULL, thread_test_helper, __UNVOLATILE(buf));
1.5       kamil     472:
1.10    ! kamil     473:        buf[0] = 0;
1.5       kamil     474:        for (i = 0; i < 10000; i++)
                    475:                continue;
1.10    ! kamil     476:        ATF_REQUIRE_EQ_MSG(buf[0], 0,
1.5       kamil     477:            "Records changed in blocked thread");
                    478:
1.1       kamil     479:        pthread_join(thread, NULL);
                    480:
1.5       kamil     481:        ATF_REQUIRE_EQ_MSG(ioctl(fd, KCOV_IOC_DISABLE), 0,
                    482:            "Unable to disable kcov");
                    483:
                    484:        common_tail(fd, buf);
                    485: }
                    486:
                    487: static void *
                    488: multiple_threads_helper(void *ptr __unused)
                    489: {
                    490:        kcov_int_t *buf;
                    491:        int fd;
1.7       kamil     492:        int mode;
1.5       kamil     493:
                    494:        buf = common_head(&fd);
1.7       kamil     495:        mode = KCOV_MODE_TRACE_PC;
                    496:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
1.5       kamil     497:            "Unable to enable kcov ");
                    498:
1.10    ! kamil     499:        buf[0] = 0;
1.5       kamil     500:
                    501:        sleep(0);
1.10    ! kamil     502:        ATF_REQUIRE_MSG(buf[0] != 0, "No records found");
1.5       kamil     503:
1.1       kamil     504:        ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
                    505:            "Unable to disable kcov");
                    506:
                    507:        common_tail(fd, buf);
1.5       kamil     508:
                    509:        return NULL;
1.1       kamil     510: }
                    511:
1.5       kamil     512: static void
                    513: kcov_multiple_threads(size_t N)
                    514: {
                    515:        pthread_t thread[32];
                    516:        size_t i;
1.9       kamil     517:        int fd;
                    518:
                    519:        /*
                    520:         * Check if /dev/kcov is available, if not bail out.
                    521:         * Verifying it on a per-thread basis is flaky.
                    522:         */
                    523:        fd = open_kcov();
                    524:        ATF_REQUIRE(close(fd) == 0);
1.5       kamil     525:
                    526:        ATF_REQUIRE(__arraycount(thread) >= N);
                    527:
1.6       kamil     528:        for (i = 0; i < N; i++)
1.5       kamil     529:                pthread_create(&thread[i], NULL, multiple_threads_helper, NULL);
                    530:
1.6       kamil     531:        for (i = 0; i < N; i++)
1.5       kamil     532:                pthread_join(thread[i], NULL);
                    533: }
                    534:
                    535: #define KCOV_MULTIPLE_THREADS(n)               \
                    536: ATF_TC_WITHOUT_HEAD(kcov_multiple_threads##n); \
                    537: ATF_TC_BODY(kcov_multiple_threads##n, tc)      \
                    538: {                                              \
                    539:                                                \
                    540:        kcov_multiple_threads(n);               \
                    541: }
                    542:
                    543: KCOV_MULTIPLE_THREADS(2)
                    544: KCOV_MULTIPLE_THREADS(4)
                    545: KCOV_MULTIPLE_THREADS(8)
                    546: KCOV_MULTIPLE_THREADS(16)
                    547: KCOV_MULTIPLE_THREADS(32)
                    548:
1.1       kamil     549: ATF_TP_ADD_TCS(tp)
                    550: {
                    551:
1.8       kamil     552:        ATF_TP_ADD_TC(tp, kcov_dup2);
1.5       kamil     553:        ATF_TP_ADD_TC(tp, kcov_multiopen);
                    554:        ATF_TP_ADD_TC(tp, kcov_open_close_open);
1.1       kamil     555:        ATF_TP_ADD_TC(tp, kcov_bufsize);
                    556:        ATF_TP_ADD_TC(tp, kcov_mmap);
                    557:        ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap);
                    558:        ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap_no_close);
                    559:        ATF_TP_ADD_TC(tp, kcov_enable);
                    560:        ATF_TP_ADD_TC(tp, kcov_enable_no_disable);
                    561:        ATF_TP_ADD_TC(tp, kcov_enable_no_disable_no_close);
                    562:        ATF_TP_ADD_TC(tp, kcov_mmap_enable_thread_close);
1.7       kamil     563:        ATF_TP_ADD_TC(tp, kcov_basic_pc);
                    564:        ATF_TP_ADD_TC(tp, kcov_basic_cmp);
1.8       kamil     565:        ATF_TP_ADD_TC(tp, kcov_basic_dup2_pc);
                    566:        ATF_TP_ADD_TC(tp, kcov_basic_dup2_cmp);
1.5       kamil     567:        ATF_TP_ADD_TC(tp, kcov_multienable_on_the_same_thread);
                    568:        ATF_TP_ADD_TC(tp, kcov_buffer_access_from_custom_thread);
1.1       kamil     569:        ATF_TP_ADD_TC(tp, kcov_thread);
1.5       kamil     570:        ATF_TP_ADD_TC(tp, kcov_multiple_threads2);
                    571:        ATF_TP_ADD_TC(tp, kcov_multiple_threads4);
                    572:        ATF_TP_ADD_TC(tp, kcov_multiple_threads8);
                    573:        ATF_TP_ADD_TC(tp, kcov_multiple_threads16);
                    574:        ATF_TP_ADD_TC(tp, kcov_multiple_threads32);
1.1       kamil     575:        return atf_no_error();
                    576: }

CVSweb <webmaster@jp.NetBSD.org>