From 012c5408507b0c85e0af14efbda51d906d620508 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 2 Dec 2015 13:19:45 +0100 Subject: [PATCH] Add backtrace to memory leak output This is an option for builds with gcc and --strict-warnings. Reviewed-by: Rich Salz --- Configure | 2 +- crypto/mem_dbg.c | 75 +++++++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Configure b/Configure index cd4f37f491..6de375736f 100755 --- a/Configure +++ b/Configure @@ -97,7 +97,7 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [experimenta # Minimum warning options... any contributions to OpenSSL should at least get # past these. -my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Wtype-limits -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DDEBUG_UNUSED"; +my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Wtype-limits -Werror -rdynamic -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DCRYPTO_MDEBUG_BACKTRACE -DREF_CHECK -DDEBUG_UNUSED"; # These are used in addition to $gcc_devteam_warn when the compiler is clang. # TODO(openssl-team): fix problems and investigate if (at least) the diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index c19847eb28..c2fe8af405 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -117,6 +117,9 @@ #include #include #include +#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__) +# include +#endif static int mh_mode = CRYPTO_MEM_CHECK_OFF; /* @@ -175,6 +178,10 @@ typedef struct mem_st unsigned long order; time_t time; APP_INFO *app_info; +#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__) + void *array[30]; + size_t array_siz; +#endif } MEM; static long options = /* extra information to be recorded */ @@ -515,6 +522,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, m->time = time(NULL); else m->time = 0; +#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__) + m->array_siz = backtrace(m->array, OSSL_NELEM(m->array)); +#endif CRYPTO_THREADID_current(&tmp.threadid); m->app_info = NULL; @@ -608,6 +618,9 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, #endif mp->addr = addr2; mp->num = num; +#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__) + mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array)); +#endif (void)lh_MEM_insert(mh, mp); } @@ -672,36 +685,36 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) amip = m->app_info; ami_cnt = 0; - if (!amip) - return; - CRYPTO_THREADID_cpy(&ti, &amip->threadid); - - do { - int buf_len; - int info_len; - - ami_cnt++; - memset(buf, '>', ami_cnt); - BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, - " thread=%lu, file=%s, line=%d, info=\"", - CRYPTO_THREADID_hash(&amip->threadid), amip->file, - amip->line); - buf_len = strlen(buf); - info_len = strlen(amip->info); - if (128 - buf_len - 3 < info_len) { - memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); - buf_len = 128 - 3; - } else { - BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len); + if (amip) { + CRYPTO_THREADID_cpy(&ti, &amip->threadid); + + do { + int buf_len; + int info_len; + + ami_cnt++; + memset(buf, '>', ami_cnt); + BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, + " thread=%lu, file=%s, line=%d, info=\"", + CRYPTO_THREADID_hash(&amip->threadid), amip->file, + amip->line); buf_len = strlen(buf); - } - BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n"); + info_len = strlen(amip->info); + if (128 - buf_len - 3 < info_len) { + memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); + buf_len = 128 - 3; + } else { + BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len); + buf_len = strlen(buf); + } + BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n"); - BIO_puts(l->bio, buf); + BIO_puts(l->bio, buf); - amip = amip->next; + amip = amip->next; + } + while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); } - while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); #ifdef LEVITTE_DEBUG_MEM if (amip) { @@ -709,6 +722,16 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) abort(); } #endif +#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__) + { + size_t i; + char **strings = backtrace_symbols(m->array, m->array_siz); + for (i = 0; i < m->array_siz; i++) + fprintf(stderr, "##> %s\n", strings[i]); + + free(strings); + } +#endif } static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) -- 2.34.1