static struct tdb_context *tdb;
+void (*external_agent_free)(void *) = free;
+
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.
ret = OTHER_FAILURE;
} else if (!tdb_deq(data, k)) {
ret = OTHER_FAILURE;
- free(data.dptr);
+ external_agent_free(data.dptr);
} else {
ret = SUCCESS;
- free(data.dptr);
+ external_agent_free(data.dptr);
}
break;
case STORE:
enum operation op,
const char *name);
+/* Hook into free() on tdb_data in external agent. */
+void (*external_agent_free)(void *);
+
/* Mapping enum -> string. */
const char *agent_return_name(enum agent_return ret);
const char *operation_name(enum operation op);
/* There's a malloc inside transaction_setup_recovery, and valgrind complains
* when we longjmp and leak it. */
-#define MAX_ALLOCATIONS 200
+#define MAX_ALLOCATIONS 10
static void *allocated[MAX_ALLOCATIONS];
+static unsigned max_alloc = 0;
static void *malloc_noleak(size_t len)
{
for (i = 0; i < MAX_ALLOCATIONS; i++)
if (!allocated[i]) {
allocated[i] = malloc(len);
+ if (i > max_alloc) {
+ max_alloc = i;
+ diag("max_alloc: %i", max_alloc);
+ }
return allocated[i];
}
diag("Too many allocations!");
for (i = 0; i < MAX_ALLOCATIONS; i++) {
if (allocated[i] == p) {
+ if (i > max_alloc) {
+ max_alloc = i;
+ diag("max_alloc: %i", max_alloc);
+ }
return allocated[i] = realloc(p, size);
}
}
plan_tests(24);
unlock_callback = maybe_die;
+ external_agent_free = free_noleak;
agent = prepare_external_agent();
if (!agent)
err(1, "preparing agent");