From 8eea28063d5729537a69abe0e31e82b044162ce3 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 5 Oct 2018 11:23:36 +0200 Subject: [PATCH] leak-detective: Use hashtable to cache ignored/whitelisted backtraces Checking for whitelisted functions in every backtrace is not very efficient. And because OpenSSL 1.1 does no proper cleanup anymore until the process is terminated there are now a lot more "leaks" to ignore. For instance, in the openssl-ikev2/rw-cert scenario, just starting and stopping the daemon (test vectors are checked) now causes 3594 whitelisted leaks compared to the 849 before. This prolonged the shutdown of the daemon on each guest in every scenario, amounting to multiple seconds of additional runtime for every affected scenario. But even with this patch there is still some overhead, compared to running the scenarios on jessie. --- src/libstrongswan/utils/leak_detective.c | 31 +++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 26d1843fa..07f33c83d 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -679,7 +679,8 @@ static int print_traces(private_leak_detective_t *this, int leaks = 0; memory_header_t *hdr; enumerator_t *enumerator; - hashtable_t *entries; + hashtable_t *entries, *ignored = NULL; + backtrace_t *bt; struct { /** associated backtrace */ backtrace_t *backtrace; @@ -694,15 +695,32 @@ static int print_traces(private_leak_detective_t *this, entries = hashtable_create((hashtable_hash_t)hash, (hashtable_equals_t)equals, 1024); + if (whitelisted) + { + ignored = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 1024); + } + lock->lock(lock); for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) { - if (whitelisted && - hdr->backtrace->contains_function(hdr->backtrace, - whitelist, countof(whitelist))) + if (whitelisted) { - (*whitelisted)++; - continue; + bt = ignored->get(ignored, hdr->backtrace); + if (!bt) + { + if (hdr->backtrace->contains_function(hdr->backtrace, whitelist, + countof(whitelist))) + { + bt = hdr->backtrace; + ignored->put(ignored, bt, bt); + } + } + if (bt) + { + (*whitelisted)++; + continue; + } } entry = entries->get(entries, hdr->backtrace); if (entry) @@ -726,6 +744,7 @@ static int print_traces(private_leak_detective_t *this, leaks++; } lock->unlock(lock); + DESTROY_IF(ignored); enumerator = entries->create_enumerator(entries); while (enumerator->enumerate(enumerator, NULL, &entry))