summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2000-03-18 15:18:27 +0000
committerBodo Möller <bodo@openssl.org>2000-03-18 15:18:27 +0000
commit6e22639f4640b702d9d8636265c685448ca64145 (patch)
tree7628095b308c3c9570acb0343b856adaaa2c9f13 /crypto
parentcde245bdcd5ff4ef580030a0c1881f307d38a6ae (diff)
Eliminate memory leaks in mem_dbg.c.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/lhash/lhash.c19
-rw-r--r--crypto/lhash/lhash.h1
-rw-r--r--crypto/mem_dbg.c43
3 files changed, 44 insertions, 19 deletions
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);