diff options
author | Bodo Möller <bodo@openssl.org> | 2000-03-18 15:18:27 +0000 |
---|---|---|
committer | Bodo Möller <bodo@openssl.org> | 2000-03-18 15:18:27 +0000 |
commit | 6e22639f4640b702d9d8636265c685448ca64145 (patch) | |
tree | 7628095b308c3c9570acb0343b856adaaa2c9f13 | |
parent | cde245bdcd5ff4ef580030a0c1881f307d38a6ae (diff) |
Eliminate memory leaks in mem_dbg.c.
-rw-r--r-- | apps/openssl.c | 2 | ||||
-rw-r--r-- | crypto/lhash/lhash.c | 19 | ||||
-rw-r--r-- | crypto/lhash/lhash.h | 1 | ||||
-rw-r--r-- | crypto/mem_dbg.c | 43 |
4 files changed, 45 insertions, 20 deletions
diff --git a/apps/openssl.c b/apps/openssl.c index 934a1c176d..a2a263062d 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -206,7 +206,7 @@ end: EVP_cleanup(); ERR_free_strings(); - + CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index 512c8bc84c..7eb92a18bc 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -422,21 +422,6 @@ static LHASH_NODE **getrn(LHASH *lh, void *data, unsigned long *rhash) return(ret); } -/* -unsigned long lh_strhash(char *str) - { - int i,l; - unsigned long ret=0; - unsigned short *s; - - if (str == NULL) return(0); - l=(strlen(str)+1)/2; - s=(unsigned short *)str; - for (i=0; i<l; i++) - ret^=(s[i]<<(i&0x0f)); - return(ret); - } */ - /* The following hash seems to work very well on normal text strings * no collisions on /usr/dict/words and it distributes on %2^n quite * well, not as good as MD5, but still good. @@ -470,3 +455,7 @@ unsigned long lh_strhash(const char *c) return((ret>>16)^ret); } +unsigned long lh_num_items(LHASH *lh) + { + return lh ? lh->num_items : 0; + } diff --git a/crypto/lhash/lhash.h b/crypto/lhash/lhash.h index 6f6eeb2698..d315fd9c6d 100644 --- a/crypto/lhash/lhash.h +++ b/crypto/lhash/lhash.h @@ -124,6 +124,7 @@ void *lh_retrieve(LHASH *lh, void *data); void lh_doall(LHASH *lh, void (*func)(/*void *b*/)); void lh_doall_arg(LHASH *lh, void (*func)(/*void *a,void *b*/),void *arg); unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(LHASH *lh); #ifndef NO_FP_API void lh_stats(LHASH *lh, FILE *out); diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index 14770c0733..a399485300 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -640,19 +640,54 @@ void CRYPTO_mem_leaks(BIO *b) MEM_LEAK ml; char buf[80]; - if (mh == NULL) return; + if (mh == NULL && amih == NULL) + return; ml.bio=b; ml.bytes=0; ml.chunks=0; - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); - lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); + MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ + if (mh != NULL) + lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); if (ml.chunks != 0) { sprintf(buf,"%ld bytes leaked in %d chunks\n", ml.bytes,ml.chunks); BIO_puts(b,buf); } + else + { + /* Make sure that, if we found no leaks, memory-leak debugging itself + * does not introduce memory leaks (which might irritate + * external debugging tools). + * (When someone enables leak checking, but does not call + * this function, we declare it to be their fault.) + * + * XXX This should be in CRYPTO_mem_leaks_cb, + * and CRYPTO_mem_leaks should be implemented by + * using CRYPTO_mem_leaks_cb. + * (Also their should be a variant of lh_doall_arg + * that takes a function pointer instead of a void *; + * this would obviate the ugly and illegal + * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. + * Otherwise the code police will come and get us.) + */ + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + if (mh != NULL) + { + lh_free(mh); + mh = NULL; + } + if (amih != NULL) + { + if (lh_num_items(amih) == 0) + { + lh_free(amih); + amih = NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + } + MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ #if 0 lh_stats_bio(mh,b); |