1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#include "memory.h"
#include "fiber.h"
#include "unit.h"
#include "trivia/util.h"
#include "errinj.h"
static struct fiber_attr default_attr;
static int
noop_f(va_list ap)
{
return 0;
}
static int
main_f(va_list ap)
{
struct slab_cache *slabc = &cord()->slabc;
size_t used_before, used_after;
struct errinj *inj;
struct fiber *fiber;
header();
plan(6);
/*
* Set non-default stack size to prevent reusing of an
* existing fiber.
*/
struct fiber_attr *fiber_attr = fiber_attr_new();
fiber_attr_setstacksize(fiber_attr, default_attr.stack_size * 2);
/*
* Clear the fiber's diagnostics area to check that failed
* fiber_new() sets an error.
*/
diag_clear(diag_get());
/*
* Check guard page setup via mprotect. We can't test the fiber
* destroy path since it clears fiber's diag.
*/
inj = errinj(ERRINJ_FIBER_MPROTECT, ERRINJ_INT);
inj->iparam = PROT_NONE;
fiber = fiber_new_ex("test_mprotect", fiber_attr, noop_f);
inj->iparam = -1;
ok(fiber == NULL, "mprotect: failed to setup fiber guard page");
ok(diag_get() != NULL, "mprotect: diag is armed after error");
/*
* Check madvise error on fiber creation.
*/
diag_clear(diag_get());
inj = errinj(ERRINJ_FIBER_MADVISE, ERRINJ_BOOL);
inj->bparam = true;
fiber = fiber_new_ex("test_madvise", fiber_attr, noop_f);
inj->bparam = false;
ok(fiber != NULL, "madvise: non critical error on madvise hint");
ok(diag_get() != NULL, "madvise: diag is armed after error");
/*
* Check if we leak on fiber destruction.
* We will print an error and result get
* compared by testing engine.
*/
fiber_attr_delete(fiber_attr);
fiber_attr = fiber_attr_new();
fiber_attr->flags |= FIBER_CUSTOM_STACK;
fiber_attr->stack_size = 64 << 10;
diag_clear(diag_get());
used_before = slabc->allocated.stats.used;
fiber = fiber_new_ex("test_madvise", fiber_attr, noop_f);
ok(fiber != NULL, "fiber with custom stack");
fiber_set_joinable(fiber, true);
inj = errinj(ERRINJ_FIBER_MPROTECT, ERRINJ_INT);
inj->iparam = PROT_READ | PROT_WRITE;
fiber_start(fiber);
fiber_join(fiber);
inj->iparam = -1;
used_after = slabc->allocated.stats.used;
ok(used_after > used_before, "expected leak detected");
fiber_attr_delete(fiber_attr);
footer();
ev_break(loop(), EVBREAK_ALL);
return check_plan();
}
int main()
{
memory_init();
fiber_init(fiber_c_invoke);
fiber_attr_create(&default_attr);
struct fiber *f = fiber_new("main", main_f);
fiber_wakeup(f);
ev_run(loop(), 0);
fiber_free();
memory_free();
return 0;
}
|