From: Tobias Brunner Date: Fri, 5 Oct 2018 09:23:36 +0000 (+0200) Subject: leak-detective: Use hashtable to cache ignored/whitelisted backtraces X-Git-Tag: 5.7.2dr3~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8eea28063d5729537a69abe0e31e82b044162ce3;p=thirdparty%2Fstrongswan.git 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. --- diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 26d1843fa2..07f33c83db 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))