From 03d2df62f614f97d2b5cf52518565ce91333ba87 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 22 Dec 2014 12:27:26 -0500 Subject: Fix a bunch of memory leaks in the unit tests. Found with valgrind --- src/or/channel.c | 3 +-- src/or/channel.h | 2 ++ src/or/transports.c | 4 +--- src/or/transports.h | 2 ++ src/test/fakechans.h | 1 + src/test/test_channel.c | 45 +++++++++++++++++++++++++++++++++------------ src/test/test_channeltls.c | 7 ++++--- src/test/test_config.c | 3 +++ src/test/test_dir.c | 13 +++++++++---- src/test/test_relay.c | 9 ++++----- 10 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/or/channel.c b/src/or/channel.c index 4826bdd0a7..cc609b5b72 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -147,7 +147,6 @@ HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash, channel_idmap_eq, 0.5, tor_reallocarray_, tor_free_); static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q); -static void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); #if 0 static int cell_queue_entry_is_padding(cell_queue_entry_t *q); #endif @@ -1569,7 +1568,7 @@ cell_queue_entry_dup(cell_queue_entry_t *q) * them) or not (we should free). */ -static void +STATIC void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off) { if (!q) return; diff --git a/src/or/channel.h b/src/or/channel.h index ec7a15f5f1..c4b909c5ad 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -380,6 +380,8 @@ struct cell_queue_entry_s { /* Cell queue functions for benefit of test suite */ STATIC int chan_cell_queue_len(const chan_cell_queue_t *queue); + +STATIC void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); #endif /* Channel operations for subclasses and internal use only */ diff --git a/src/or/transports.c b/src/or/transports.c index 2623f807d0..7999be3d33 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -112,8 +112,6 @@ static void parse_method_error(const char *line, int is_server_method); #define parse_server_method_error(l) parse_method_error(l, 1) #define parse_client_method_error(l) parse_method_error(l, 0) -static INLINE void free_execve_args(char **arg); - /** Managed proxy protocol strings */ #define PROTO_ENV_ERROR "ENV-ERROR" #define PROTO_NEG_SUCCESS "VERSION" @@ -1502,7 +1500,7 @@ pt_kickstart_proxy, (const smartlist_t *transport_list, /** Frees the array of pointers in arg used as arguments to execve(2). */ -static INLINE void +STATIC void free_execve_args(char **arg) { char **tmp = arg; diff --git a/src/or/transports.h b/src/or/transports.h index 2958d5e187..8f60760de8 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -131,6 +131,8 @@ STATIC int configure_proxy(managed_proxy_t *mp); STATIC char* get_pt_proxy_uri(void); +STATIC void free_execve_args(char **arg); + #endif #endif diff --git a/src/test/fakechans.h b/src/test/fakechans.h index b129ab49a5..230abe4da6 100644 --- a/src/test/fakechans.h +++ b/src/test/fakechans.h @@ -12,6 +12,7 @@ void make_fake_cell(cell_t *c); void make_fake_var_cell(var_cell_t *c); channel_t * new_fake_channel(void); +void free_fake_channel(channel_t *c); /* Also exposes some a mock used by both test_channel.c and test_relay.c */ void scheduler_channel_has_waiting_cells_mock(channel_t *ch); diff --git a/src/test/test_channel.c b/src/test/test_channel.c index b1f1bdb435..0766415510 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -430,6 +430,27 @@ new_fake_channel(void) return chan; } +void +free_fake_channel(channel_t *chan) +{ + cell_queue_entry_t *cell, *cell_tmp; + + if (! chan) + return; + + if (chan->cmux) + circuitmux_free(chan->cmux); + + TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); + } + TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) { + cell_queue_entry_free(cell, 0); + } + + tor_free(chan); +} + /** * Counter query for scheduler_channel_has_waiting_cells_mock() */ @@ -610,7 +631,7 @@ test_channel_dumpstats(void *arg) done: tor_free(cell); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_channel_doesnt_want_writes); UNMOCK(scheduler_release_channel); @@ -748,6 +769,8 @@ test_channel_flushmux(void *arg) test_cmux_cells = 0; done: + if (ch) + circuitmux_free(ch->cmux); tor_free(ch); UNMOCK(channel_flush_from_first_active_circuit); @@ -831,7 +854,7 @@ test_channel_incoming(void *arg) ch = NULL; done: - tor_free(ch); + free_fake_channel(ch); tor_free(cell); tor_free(var_cell); @@ -944,8 +967,8 @@ test_channel_lifecycle(void *arg) tt_int_op(test_releases_count, ==, init_releases_count + 4); done: - tor_free(ch1); - tor_free(ch2); + free_fake_channel(ch1); + free_fake_channel(ch2); UNMOCK(scheduler_channel_doesnt_want_writes); UNMOCK(scheduler_release_channel); @@ -1214,6 +1237,7 @@ test_channel_multi(void *arg) cell = tor_malloc_zero(sizeof(cell_t)); make_fake_cell(cell); channel_write_cell(ch2, cell); + cell = NULL; /* Check the estimates */ channel_update_xmit_queue_size(ch1); @@ -1248,8 +1272,8 @@ test_channel_multi(void *arg) UNMOCK(scheduler_release_channel); done: - tor_free(ch1); - tor_free(ch2); + free_fake_channel(ch1); + free_fake_channel(ch2); return; } @@ -1279,9 +1303,6 @@ test_channel_queue_impossible(void *arg) init_cell_pool(); #endif /* ENABLE_MEMPOOLS */ - packed_cell = packed_cell_new(); - tt_assert(packed_cell); - ch = new_fake_channel(); tt_assert(ch); @@ -1403,7 +1424,7 @@ test_channel_queue_impossible(void *arg) tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), ==, 0); done: - tor_free(ch); + free_fake_channel(ch); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ @@ -1532,7 +1553,7 @@ test_channel_queue_size(void *arg) UNMOCK(scheduler_release_channel); done: - tor_free(ch); + free_fake_channel(ch); return; } @@ -1654,7 +1675,7 @@ test_channel_write(void *arg) #endif /* ENABLE_MEMPOOLS */ done: - tor_free(ch); + free_fake_channel(ch); tor_free(var_cell); tor_free(cell); packed_cell_free(packed_cell); diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 45e24dfbec..89c75d8732 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -80,7 +80,7 @@ test_channeltls_create(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -167,7 +167,7 @@ test_channeltls_num_bytes_queued(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -241,7 +241,7 @@ test_channeltls_overhead_estimate(void *arg) */ ch->close = tlschan_fake_close_method; channel_mark_for_close(ch); - tor_free(ch); + free_fake_channel(ch); UNMOCK(scheduler_release_channel); } @@ -304,6 +304,7 @@ tlschan_fake_close_method(channel_t *chan) tt_assert(tlschan != NULL); /* Just free the fake orconn */ + tor_free(tlschan->conn->base_.address); tor_free(tlschan->conn); channel_closed(chan); diff --git a/src/test/test_config.c b/src/test/test_config.c index dcb4e92c56..ea0c39759f 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -6,6 +6,7 @@ #include "orconfig.h" #define CONFIG_PRIVATE +#define PT_PRIVATE #include "or.h" #include "addressmap.h" #include "config.h" @@ -578,6 +579,8 @@ pt_kickstart_proxy_mock(const smartlist_t *transport_list, /* XXXX check that args are as expected. */ ++pt_kickstart_proxy_mock_call_count; + + free_execve_args(proxy_argv); } static int diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 2659fbcfb8..4cd8aa8759 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -387,6 +387,12 @@ test_dir_routerparse_bad(void *arg) #include "example_extrainfo.inc" +static void +routerinfo_free_wrapper_(void *arg) +{ + routerinfo_free(arg); +} + static void test_dir_extrainfo_parsing(void *arg) { @@ -455,9 +461,9 @@ test_dir_extrainfo_parsing(void *arg) #undef CHECK_FAIL done: + extrainfo_free(ei); routerinfo_free(ri); - /* XXXX elements should get freed too */ - digestmap_free((digestmap_t*)map, NULL); + digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); } static void @@ -552,9 +558,8 @@ test_dir_parse_router_list(void *arg) SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); smartlist_free(chunks); routerinfo_free(ri); - /* XXXX this leaks: */ if (map) { - digestmap_free((digestmap_t*)map, NULL); + digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); router_get_routerlist()->identity_map = (struct digest_ri_map_t*)digestmap_new(); } diff --git a/src/test/test_relay.c b/src/test/test_relay.c index 38d1d96703..fbe7fafc06 100644 --- a/src/test/test_relay.c +++ b/src/test/test_relay.c @@ -111,15 +111,14 @@ test_relay_append_cell_to_circuit_queue(void *arg) /* Shut down channels */ channel_free_all(); - nchan = pchan = NULL; done: tor_free(cell); + cell_queue_clear(&orcirc->base_.n_chan_cells); + cell_queue_clear(&orcirc->p_chan_cells); tor_free(orcirc); - if (nchan && nchan->cmux) circuitmux_free(nchan->cmux); - tor_free(nchan); - if (pchan && pchan->cmux) circuitmux_free(pchan->cmux); - tor_free(pchan); + free_fake_channel(nchan); + free_fake_channel(pchan); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ -- cgit v1.2.3-54-g00ecf