summaryrefslogtreecommitdiffstats
path: root/crypto/mem_dbg.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2015-12-02 13:19:45 +0100
committerRichard Levitte <levitte@openssl.org>2015-12-02 16:49:08 +0100
commit012c5408507b0c85e0af14efbda51d906d620508 (patch)
treea728f7fabe4df53ca92ec5b75cbfc80082e87148 /crypto/mem_dbg.c
parentcrypto/sparcv9cap.c: add SIGILL-free feature detection for Solaris. (diff)
downloadopenssl-012c5408507b0c85e0af14efbda51d906d620508.tar.xz
openssl-012c5408507b0c85e0af14efbda51d906d620508.zip
Add backtrace to memory leak output
This is an option for builds with gcc and --strict-warnings. Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/mem_dbg.c')
-rw-r--r--crypto/mem_dbg.c75
1 files changed, 49 insertions, 26 deletions
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 <openssl/buffer.h>
#include <openssl/bio.h>
#include <openssl/lhash.h>
+#if defined(CRYPTO_MDEBUG_BACKTRACE) && defined(__GNUC__)
+# include <execinfo.h>
+#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)