Skip to content
Snippets Groups Projects
Commit 9602caf6 authored by Sven M. Hallberg's avatar Sven M. Hallberg
Browse files

test out-of-memory handling with a mock allocator

parent 7b13a828
No related branches found
No related tags found
No related merge requests found
......@@ -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);
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);
// 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);
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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment