commit addd18172167e549b28efc8cf1132e1b8f9d3972 Author: Nick Mathewson nickm@torproject.org Date: Mon Mar 28 10:37:22 2016 -0400
Fix memory leak in TestingEnableCellStatsEvent
Only when we were actually flushing the cell stats to a controller would we free them. Thus, they could stay in RAM even after the circuit was freed (eg if we didn't have any controllers).
Fixes bug 18673; bugfix on 0.2.5.1-alpha. --- changes/bug18673 | 4 ++++ src/or/circuitlist.c | 14 ++++++++++++++ src/or/circuitlist.h | 2 ++ src/or/control.c | 6 ++---- 4 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/changes/bug18673 b/changes/bug18673 new file mode 100644 index 0000000..5d61617 --- /dev/null +++ b/changes/bug18673 @@ -0,0 +1,4 @@ + o Minor bugfixes (memory leak): + - Fix a small memory leak that would occur when the + TestingEnableCellStatsEvent option was turned on. Fixes bug 18673; + bugfix on 0.2.5.2-alpha. diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index d6532dd..670c5b3 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -756,6 +756,18 @@ or_circuit_new(circid_t p_circ_id, channel_t *p_chan) return circ; }
+/** Free all storage held in circ->testing_cell_stats */ +void +circuit_clear_testing_cell_stats(circuit_t *circ) +{ + if (!circ) + return; + SMARTLIST_FOREACH(circ->testing_cell_stats, testing_cell_stats_entry_t *, + ent, tor_free(ent)); + smartlist_free(circ->testing_cell_stats); + circ->testing_cell_stats = NULL; +} + /** Deallocate space associated with circ. */ STATIC void @@ -767,6 +779,8 @@ circuit_free(circuit_t *circ) if (!circ) return;
+ circuit_clear_testing_cell_stats(circ); + if (CIRCUIT_IS_ORIGIN(circ)) { origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); mem = ocirc; diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index e4f1f47..2707b42 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -71,6 +71,8 @@ void assert_circuit_ok(const circuit_t *c); void circuit_free_all(void); void circuits_handle_oom(size_t current_allocation);
+void circuit_clear_testing_cell_stats(circuit_t *circ); + void channel_note_destroy_pending(channel_t *chan, circid_t id); MOCK_DECL(void, channel_note_destroy_not_pending, (channel_t *chan, circid_t id)); diff --git a/src/or/control.c b/src/or/control.c index 2bec8f9..655b4dd 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -4971,7 +4971,7 @@ sum_up_cell_stats_by_command(circuit_t *circ, cell_stats_t *cell_stats) { memset(cell_stats, 0, sizeof(cell_stats_t)); SMARTLIST_FOREACH_BEGIN(circ->testing_cell_stats, - testing_cell_stats_entry_t *, ent) { + const testing_cell_stats_entry_t *, ent) { tor_assert(ent->command <= CELL_COMMAND_MAX_); if (!ent->removed && !ent->exitward) { cell_stats->added_cells_appward[ent->command] += 1; @@ -4984,10 +4984,8 @@ sum_up_cell_stats_by_command(circuit_t *circ, cell_stats_t *cell_stats) cell_stats->removed_cells_exitward[ent->command] += 1; cell_stats->total_time_exitward[ent->command] += ent->waiting_time * 10; } - tor_free(ent); } SMARTLIST_FOREACH_END(ent); - smartlist_free(circ->testing_cell_stats); - circ->testing_cell_stats = NULL; + circuit_clear_testing_cell_stats(circ); }
/** Helper: append a cell statistics string to <code>event_parts</code>,
tor-commits@lists.torproject.org