diff options
Diffstat (limited to 'src/libstrongswan/utils/leak_detective.c')
-rw-r--r-- | src/libstrongswan/utils/leak_detective.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 2f8a7187c..0673878a5 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -207,6 +207,7 @@ char *whitelist[] = { "ENGINE_load_builtin_engines", "OPENSSL_config", "ecdsa_check", + "ERR_put_error", /* libgcrypt */ "gcry_control", "gcry_check_version", @@ -233,39 +234,45 @@ static bool is_whitelisted(backtrace_t *backtrace) /** * Report leaks at library destruction */ -void report_leaks() +static void report(private_leak_detective_t *this, bool detailed) { - memory_header_t *hdr; - int leaks = 0, whitelisted = 0; - - for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) + if (lib->leak_detective) { - if (is_whitelisted(hdr->backtrace)) + memory_header_t *hdr; + int leaks = 0, whitelisted = 0; + + for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) { - whitelisted++; + if (is_whitelisted(hdr->backtrace)) + { + whitelisted++; + } + else + { + fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1); + /* skip the first frame, contains leak detective logic */ + hdr->backtrace->log(hdr->backtrace, stderr, detailed); + leaks++; + } } - else + switch (leaks) { - fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1); - /* skip the first frame, contains leak detective logic */ - hdr->backtrace->log(hdr->backtrace, stderr); - leaks++; + case 0: + fprintf(stderr, "No leaks detected"); + break; + case 1: + fprintf(stderr, "One leak detected"); + break; + default: + fprintf(stderr, "%d leaks detected", leaks); + break; } + fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted); } - - switch (leaks) + else { - case 0: - fprintf(stderr, "No leaks detected"); - break; - case 1: - fprintf(stderr, "One leak detected"); - break; - default: - fprintf(stderr, "%d leaks detected", leaks); - break; + fprintf(stderr, "Leak detective disabled\n"); } - fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted); } /** @@ -395,7 +402,7 @@ void free_hook(void *ptr, const void *caller) fprintf(stderr, "freeing invalid memory (%p)", ptr); } backtrace = backtrace_create(3); - backtrace->log(backtrace, stderr); + backtrace->log(backtrace, stderr, TRUE); backtrace->destroy(backtrace); } else @@ -454,7 +461,7 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) "header magic 0x%x, tail magic 0x%x:\n", old, hdr->magic, tail->magic); backtrace = backtrace_create(3); - backtrace->log(backtrace, stderr); + backtrace->log(backtrace, stderr, TRUE); backtrace->destroy(backtrace); } /* clear tail magic, allocate, set tail magic */ @@ -487,7 +494,6 @@ static void destroy(private_leak_detective_t *this) if (installed) { uninstall_hooks(); - report_leaks(); } free(this); } @@ -499,6 +505,7 @@ leak_detective_t *leak_detective_create() { private_leak_detective_t *this = malloc_thing(private_leak_detective_t); + this->public.report = (void(*)(leak_detective_t*,bool))report; this->public.destroy = (void(*)(leak_detective_t*))destroy; if (getenv("LEAK_DETECTIVE_DISABLE") == NULL) |