diff options
author | David Goldblatt <davidgoldblatt@fb.com> | 2017-03-29 00:30:54 (GMT) |
---|---|---|
committer | David Goldblatt <davidtgoldblatt@gmail.com> | 2017-04-07 21:10:27 (GMT) |
commit | 0a0fcd3e6a0816f0a56fa852416d0ece861c0abb (patch) | |
tree | 49b3c934dd8308e7c3bf31692184ef72bb1e8a0d /test/src | |
parent | 36bd90b96212772f1adbd421a6b091b542278995 (diff) | |
download | jemalloc-0a0fcd3e6a0816f0a56fa852416d0ece861c0abb.zip jemalloc-0a0fcd3e6a0816f0a56fa852416d0ece861c0abb.tar.gz jemalloc-0a0fcd3e6a0816f0a56fa852416d0ece861c0abb.tar.bz2 |
Add hooking functionality
This allows us to hook chosen functions and do interesting things there (in
particular: reentrancy checking).
Diffstat (limited to 'test/src')
-rw-r--r-- | test/src/test.c | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/test/src/test.c b/test/src/test.c index c5101d4..fe6dc60 100644 --- a/test/src/test.c +++ b/test/src/test.c @@ -1,10 +1,42 @@ #include "test/jemalloc_test.h" +/* Test status state. */ + static unsigned test_count = 0; static test_status_t test_counts[test_status_count] = {0, 0, 0}; static test_status_t test_status = test_status_pass; static const char * test_name = ""; +/* Reentrancy testing helpers. */ + +#define NUM_REENTRANT_ALLOCS 20 +static bool reentrant = false; +static bool hook_ran = false; +static void *to_free[NUM_REENTRANT_ALLOCS]; + +static void +reentrancy_hook() { + hook_ran = true; + hooks_libc_hook = NULL; + + void *to_free_local[NUM_REENTRANT_ALLOCS]; + size_t alloc_size = 1; + for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) { + to_free[i] = malloc(alloc_size); + to_free_local[i] = malloc(alloc_size); + alloc_size *= 2; + } + for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) { + free(to_free_local[i]); + } +} + +/* Actual test infrastructure. */ +bool +test_is_reentrant() { + return reentrant; +} + JEMALLOC_FORMAT_PRINTF(1, 2) void test_skip(const char *format, ...) { @@ -49,11 +81,13 @@ p_test_init(const char *name) { void p_test_fini(void) { test_counts[test_status]++; - malloc_printf("%s: %s\n", test_name, test_status_string(test_status)); + malloc_printf("%s: %s (%s)\n", test_name, + test_status_string(test_status), + reentrant ? "reentrant" : "non-reentrant"); } static test_status_t -p_test_impl(bool do_malloc_init, test_t *t, va_list ap) { +p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) { test_status_t ret; if (do_malloc_init) { @@ -71,10 +105,27 @@ p_test_impl(bool do_malloc_init, test_t *t, va_list ap) { ret = test_status_pass; for (; t != NULL; t = va_arg(ap, test_t *)) { + /* Non-reentrant run. */ + reentrant = false; t(); if (test_status > ret) { ret = test_status; } + /* Reentrant run. */ + if (do_reentrant) { + reentrant = true; + hooks_libc_hook = &reentrancy_hook; + t(); + if (test_status > ret) { + ret = test_status; + } + if (hook_ran) { + hook_ran = false; + for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) { + free(to_free[i]); + } + } + } } malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n", @@ -95,7 +146,20 @@ p_test(test_t *t, ...) { ret = test_status_pass; va_start(ap, t); - ret = p_test_impl(true, t, ap); + ret = p_test_impl(true, true, t, ap); + va_end(ap); + + return ret; +} + +test_status_t +p_test_no_reentrancy(test_t *t, ...) { + test_status_t ret; + va_list ap; + + ret = test_status_pass; + va_start(ap, t); + ret = p_test_impl(true, false, t, ap); va_end(ap); return ret; @@ -108,7 +172,11 @@ p_test_no_malloc_init(test_t *t, ...) { ret = test_status_pass; va_start(ap, t); - ret = p_test_impl(false, t, ap); + /* + * We also omit reentrancy from bootstrapping tests, since we don't + * (yet) care about general reentrancy during bootstrapping. + */ + ret = p_test_impl(false, false, t, ap); va_end(ap); return ret; |