test out-of-memory handling with a mock allocator
This commit is contained in:
parent
7b13a82851
commit
9602caf64f
1 changed files with 38 additions and 29 deletions
67
src/t_misc.c
67
src/t_misc.c
|
|
@ -30,41 +30,50 @@ static void test_tt_registry(void) {
|
|||
g_check_cmp_int32(h_get_token_type_number("com.upstandinghackers.test.unkown_token_type"), ==, 0);
|
||||
}
|
||||
|
||||
// perform a big allocation during parsing to trigger out-of-memory handling
|
||||
static HParsedToken *act_big_alloc(const HParseResult *r, void *user) {
|
||||
void *buf = h_arena_malloc(r->arena, 500*1024*1024);
|
||||
// test out-of-memory handling with a selectively failing allocator
|
||||
static void *fail_alloc(HAllocator *mm__, size_t size) {
|
||||
if(size - 0xdead <= 0x30) // allow for overhead of arena link structure
|
||||
return NULL;
|
||||
return system_allocator.alloc(&system_allocator, size);
|
||||
}
|
||||
static void *fail_realloc(HAllocator *mm__, void *ptr, size_t size) {
|
||||
return system_allocator.realloc(&system_allocator, ptr, size);
|
||||
}
|
||||
static void fail_free(HAllocator *mm__, void *ptr) {
|
||||
return system_allocator.free(&system_allocator, ptr);
|
||||
}
|
||||
static HAllocator fail_allocator = {fail_alloc, fail_realloc, fail_free};
|
||||
static HParsedToken *act_oom(const HParseResult *r, void *user) {
|
||||
void *buf = h_arena_malloc(r->arena, 0xdead);
|
||||
assert(buf != NULL);
|
||||
g_test_message("Memory allocation was supposed to fail");
|
||||
return NULL;
|
||||
return NULL; // succeed with null token
|
||||
}
|
||||
static void test_oom(void) {
|
||||
HParser *p = h_action(h_ch('x'), act_big_alloc, NULL);
|
||||
HParser *p = h_action(h_ch('x'), act_oom, NULL);
|
||||
// this should always fail, but never crash
|
||||
|
||||
struct rlimit bak, lim;
|
||||
int i;
|
||||
i = getrlimit(RLIMIT_DATA, &bak);
|
||||
assert(i == 0);
|
||||
lim.rlim_cur = 499*1024*1024; // never enough
|
||||
if(lim.rlim_cur > bak.rlim_max)
|
||||
lim.rlim_cur = bak.rlim_max;
|
||||
lim.rlim_max = bak.rlim_max;
|
||||
i = setrlimit(RLIMIT_DATA, &lim);
|
||||
assert(i == 0);
|
||||
// sanity-check: parses should succeed with the normal allocator...
|
||||
g_check_parse_ok(p, PB_PACKRAT, "x",1);
|
||||
g_check_parse_ok(p, PB_REGULAR, "x",1);
|
||||
g_check_parse_ok(p, PB_LLk, "x",1);
|
||||
g_check_parse_ok(p, PB_LALR, "x",1);
|
||||
g_check_parse_ok(p, PB_GLR, "x",1);
|
||||
//XXX g_check_parse_chunks_ok(p, PB_REGULAR, "",0, "x",1);
|
||||
g_check_parse_chunks_ok(p, PB_LLk, "",0, "x",1);
|
||||
g_check_parse_chunks_ok(p, PB_LALR, "",0, "x",1);
|
||||
//XXX g_check_parse_chunks_ok(p, PB_GLR, "",0, "x",1);
|
||||
|
||||
g_check_parse_failed(p, PB_PACKRAT, "x",1);
|
||||
g_check_parse_failed(p, PB_REGULAR, "x",1);
|
||||
g_check_parse_failed(p, PB_LLk, "x",1);
|
||||
g_check_parse_failed(p, PB_LALR, "x",1);
|
||||
g_check_parse_failed(p, PB_GLR, "x",1);
|
||||
|
||||
//g_check_parse_chunks_failed(p, PB_REGULAR, "",0, "x",1);
|
||||
g_check_parse_chunks_failed(p, PB_LLk, "",0, "x",1);
|
||||
g_check_parse_chunks_failed(p, PB_LALR, "",0, "x",1);
|
||||
//g_check_parse_chunks_failed(p, PB_GLR, "",0, "x",1);
|
||||
|
||||
i = setrlimit(RLIMIT_DATA, &bak);
|
||||
assert(i == 0);
|
||||
// ...and fail gracefully with the broken one
|
||||
HAllocator *mm__ = &fail_allocator;
|
||||
g_check_parse_failed__m(mm__, p, PB_PACKRAT, "x",1);
|
||||
g_check_parse_failed__m(mm__, p, PB_REGULAR, "x",1);
|
||||
g_check_parse_failed__m(mm__, p, PB_LLk, "x",1);
|
||||
g_check_parse_failed__m(mm__, p, PB_LALR, "x",1);
|
||||
g_check_parse_failed__m(mm__, p, PB_GLR, "x",1);
|
||||
//XXX g_check_parse_chunks_failed__m(mm__, p, PB_REGULAR, "",0, "x",1);
|
||||
g_check_parse_chunks_failed__m(mm__, p, PB_LLk, "",0, "x",1);
|
||||
g_check_parse_chunks_failed__m(mm__, p, PB_LALR, "",0, "x",1);
|
||||
//XXX g_check_parse_chunks_failed__m(mm__, p, PB_GLR, "",0, "x",1);
|
||||
}
|
||||
|
||||
void register_misc_tests(void) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue