From 59e2d3ff253250dd26c7589bb30a59f5355cba58 Mon Sep 17 00:00:00 2001 From: Ole Kristian Morud Date: Tue, 16 Jan 2024 02:20:55 +0100 Subject: [PATCH] Add more tests --- test/test_arena.c | 86 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/test/test_arena.c b/test/test_arena.c index 2498e37..a94d7a0 100644 --- a/test/test_arena.c +++ b/test/test_arena.c @@ -2,19 +2,15 @@ #include "arena.h" #include "knob.h" -#include // exit(), EXIT_FAILURE -#include // memset +#include #include // fprintf +#include // exit, EXIT_FAILURE +#include // memset +#include // waitpid #include // sysconf - - int main() { - // calling print functions early makes my strace output more readable - printf("\n"); - fprintf(stderr, "\n"); - size_t page_size = sysconf(_SC_PAGE_SIZE); if (page_size == -1) { perror("sysconf"); @@ -26,14 +22,15 @@ int main() * =============================== */ { - write(STDERR_FILENO, "\n\n", 2); + fprintf(stderr, "creating new arena with arena_new()\n "); arena_t a = arena_new(); if (arena_new_failed(&a)) { fprintf(stderr, "arena_new failed\n"); exit(EXIT_FAILURE); } + fprintf(stderr, "OK\n"); - // test many small allocations + fprintf(stderr, "attempting many small allocations\n "); for (int i = 0; i < page_size * 8; i++) { char* s = arena_alloc(&a, 4 * sizeof *s); if (!s) { @@ -42,23 +39,26 @@ int main() } memset(s, 'a', 4); } + fprintf(stderr, "OK\n"); - // test a few allocations above the cap*2 + fprintf(stderr, "testing allocations of cap * 3 + 123\n "); for (int i = 0; i < 2; i++) { size_t n = a.cap * 3 + 123; - printf("allocating %d bytes\n", n); volatile char* s = arena_alloc(&a, n); if (!s) { fprintf(stderr, "arena_alloc failed\n"); exit(EXIT_FAILURE); } } + fprintf(stderr, "OK\n"); + fprintf(stderr, "calling arena_delete() on arena from arena_new()\n "); int ok = arena_delete(&a); if (ok == -1) { fprintf(stderr, "arena_delete failed\n"); exit(EXIT_FAILURE); } + fprintf(stderr, "OK\n"); } /* @@ -66,13 +66,18 @@ int main() * =============================== */ { - write(STDERR_FILENO, "\n\n", 2); + fprintf(stderr, "creating new arena with arena_attach() and malloc()\n "); char* p = malloc(page_size); + if (!p) { + perror("malloc"); + exit(EXIT_FAILURE); + } arena_t a = arena_attach(p, page_size); + fprintf(stderr, "OK\n"); bool failed = false; - // attempt to grow more than the buffer size + fprintf(stderr, "try to grow more than the buffer size (should fail)\n "); int i; for (i=0; i < page_size + 1; i++) { char* s = arena_alloc(&a, 8); @@ -81,27 +86,68 @@ int main() break; } } - if (!failed) { fprintf(stderr, "allocation was supposed to fail, but didn't\n"); exit(EXIT_FAILURE); } else if (i != page_size / KNOB_ALIGNMENT ) { - fprintf(stderr, "allocation failed after %d allocations, should instead fail after %d. Bad!\n", i, page_size/sizeof(void*)); + fprintf(stderr, "allocation failed after %d allocations, but should fail after %d!\n", i, page_size/sizeof(void*)); exit(EXIT_FAILURE); - } else { - fprintf(stderr, "arena from arena_attach failed after %d allocations, good!", i); } + fprintf(stderr, "OK\n"); - // deleting an arena not made with arena_new should fail + fprintf(stderr, "deleting an arena not made with arena_new (should fail)\n "); int ok = arena_delete(&a); if (ok != -1) { fprintf(stderr, "arena_delete was supposed to fail, but didn't\n"); exit(EXIT_FAILURE); } + fprintf(stderr, "OK\n"); free(arena_detatch(a)); } - + /* + * test the memory protection + * =============================== + */ + { + fprintf(stderr, "attempting to access memory beyond arena cap (should sigsegv)\n "); + pid_t p; + switch (p = fork()) { + case -1: /* error */ + perror(fork()); + exit(EXIT_FAILURE); + + case 0: /* child */ + arena_t a = arena_new(); + if (arena_new_failed(&a)) { + fprintf(stderr, "arena_new failed\n"); + exit(EXIT_FAILURE); + } + + char* s = arena_alloc(&a, 12345); + if (!s) { + fprintf(stderr, "arena_alloc failed\n"); + exit(EXIT_FAILURE); + } + + // should sigsegv + a.data[a.cap] = 1; + exit(EXIT_SUCCESS); + } + + int status; + int ok = waitpid(p, &status, 0); + if (!ok) { + perror("waitpid"); + } + + if (!( WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) { + fprintf(stderr, "allocating beyond arena cap succeeded when it shouldn't!\n"); + exit(EXIT_FAILURE); + } + fprintf(stderr, "OK\n"); + } + return EXIT_SUCCESS; }