Fixed memory leak that could occur after upb_arena_fuse().

Also added valgrind testing for Kokoro.
pull/13171/head
Joshua Haberman 5 years ago
parent 35abcc248b
commit 086a68d191
  1. 2
      kokoro/ubuntu/build.sh
  2. 4
      tests/test_cpp.cc
  3. 30
      upb/upb.c

@ -31,4 +31,6 @@ if [[ $(uname) = "Linux" ]]; then
# For some reason kokoro doesn't have Clang available right now.
#CC=clang CXX=clang++ bazel test -c dbg --copt=-fsanitize=undefined --copt=-fno-sanitize=function,vptr --linkopt=-fsanitize=undefined --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 -- :all -:test_lua
bazel test --run_under='valgrind --leak-check=full --error-exitcode=1' :all -- -:test_conformance_upb -:cmake_build
fi

@ -947,8 +947,8 @@ void TestArena() {
arena1.Fuse(arena2);
upb_arena_malloc(arena1.ptr(), 1);
upb_arena_malloc(arena2.ptr(), 1);
upb_arena_malloc(arena1.ptr(), 10000);
upb_arena_malloc(arena2.ptr(), 10000);
}
}

@ -106,15 +106,28 @@ struct upb_arena {
static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
static upb_arena *arena_findroot(upb_arena *a) {
/* Path splitting keeps time complexity down, see:
* https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
while (a->parent != a) {
upb_arena *next = a->parent;
a->parent = next->parent;
a = next;
}
return a;
}
static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) {
mem_block *block = ptr;
upb_arena *root = arena_findroot(a);
block->next = a->freelist;
/* The block is for arena |a|, but should appear in the freelist of |root|. */
block->next = root->freelist;
block->size = (uint32_t)size;
block->cleanups = 0;
a->freelist = block;
root->freelist = block;
a->last_size = block->size;
if (!a->freelist_tail) a->freelist_tail = block;
if (!root->freelist_tail) root->freelist_tail = block;
a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
a->head.end = UPB_PTR_AT(block, size, char);
@ -149,17 +162,6 @@ static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
return upb_arena_realloc(a, ptr, oldsize, size);
}
static upb_arena *arena_findroot(upb_arena *a) {
/* Path splitting keeps time complexity down, see:
* https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
while (a->parent != a) {
upb_arena *next = a->parent;
a->parent = next->parent;
a = next;
}
return a;
}
/* Public Arena API ***********************************************************/
upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {

Loading…
Cancel
Save