Commit d9cbd7d4 authored by Rusty Russell's avatar Rusty Russell

tdb2: test: fix run-57-die-during-transaction.c to be more efficient.

We track malloc and free, but we didn't catch the free() inside
external_agent, which means that our list of allocations keeps
growing.  Particularly under valgrind, which re-uses memory less than
the glibc allocator.
parent 1be090a2
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
static struct tdb_context *tdb; static struct tdb_context *tdb;
void (*external_agent_free)(void *) = free;
static enum TDB_ERROR clear_if_first(int fd, void *arg) static enum TDB_ERROR clear_if_first(int fd, void *arg)
{ {
/* We hold a lock offset 4 always, so we can tell if anyone is holding it. /* We hold a lock offset 4 always, so we can tell if anyone is holding it.
...@@ -100,10 +102,10 @@ static enum agent_return do_operation(enum operation op, const char *name) ...@@ -100,10 +102,10 @@ static enum agent_return do_operation(enum operation op, const char *name)
ret = OTHER_FAILURE; ret = OTHER_FAILURE;
} else if (!tdb_deq(data, k)) { } else if (!tdb_deq(data, k)) {
ret = OTHER_FAILURE; ret = OTHER_FAILURE;
free(data.dptr); external_agent_free(data.dptr);
} else { } else {
ret = SUCCESS; ret = SUCCESS;
free(data.dptr); external_agent_free(data.dptr);
} }
break; break;
case STORE: case STORE:
......
...@@ -35,6 +35,9 @@ enum agent_return external_agent_operation(struct agent *handle, ...@@ -35,6 +35,9 @@ enum agent_return external_agent_operation(struct agent *handle,
enum operation op, enum operation op,
const char *name); const char *name);
/* Hook into free() on tdb_data in external agent. */
void (*external_agent_free)(void *);
/* Mapping enum -> string. */ /* Mapping enum -> string. */
const char *agent_return_name(enum agent_return ret); const char *agent_return_name(enum agent_return ret);
const char *operation_name(enum operation op); const char *operation_name(enum operation op);
......
...@@ -15,8 +15,9 @@ static int ftruncate_check(int fd, off_t length); ...@@ -15,8 +15,9 @@ static int ftruncate_check(int fd, off_t length);
/* There's a malloc inside transaction_setup_recovery, and valgrind complains /* There's a malloc inside transaction_setup_recovery, and valgrind complains
* when we longjmp and leak it. */ * when we longjmp and leak it. */
#define MAX_ALLOCATIONS 200 #define MAX_ALLOCATIONS 10
static void *allocated[MAX_ALLOCATIONS]; static void *allocated[MAX_ALLOCATIONS];
static unsigned max_alloc = 0;
static void *malloc_noleak(size_t len) static void *malloc_noleak(size_t len)
{ {
...@@ -25,6 +26,10 @@ static void *malloc_noleak(size_t len) ...@@ -25,6 +26,10 @@ static void *malloc_noleak(size_t len)
for (i = 0; i < MAX_ALLOCATIONS; i++) for (i = 0; i < MAX_ALLOCATIONS; i++)
if (!allocated[i]) { if (!allocated[i]) {
allocated[i] = malloc(len); allocated[i] = malloc(len);
if (i > max_alloc) {
max_alloc = i;
diag("max_alloc: %i", max_alloc);
}
return allocated[i]; return allocated[i];
} }
diag("Too many allocations!"); diag("Too many allocations!");
...@@ -37,6 +42,10 @@ static void *realloc_noleak(void *p, size_t size) ...@@ -37,6 +42,10 @@ static void *realloc_noleak(void *p, size_t size)
for (i = 0; i < MAX_ALLOCATIONS; i++) { for (i = 0; i < MAX_ALLOCATIONS; i++) {
if (allocated[i] == p) { if (allocated[i] == p) {
if (i > max_alloc) {
max_alloc = i;
diag("max_alloc: %i", max_alloc);
}
return allocated[i] = realloc(p, size); return allocated[i] = realloc(p, size);
} }
} }
...@@ -270,6 +279,7 @@ int main(int argc, char *argv[]) ...@@ -270,6 +279,7 @@ int main(int argc, char *argv[])
plan_tests(24); plan_tests(24);
unlock_callback = maybe_die; unlock_callback = maybe_die;
external_agent_free = free_noleak;
agent = prepare_external_agent(); agent = prepare_external_agent();
if (!agent) if (!agent)
err(1, "preparing agent"); err(1, "preparing agent");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment