Eliminate memory leaks in mem_dbg.c.
authorBodo Möller <bodo@openssl.org>
Sat, 18 Mar 2000 15:18:27 +0000 (15:18 +0000)
committerBodo Möller <bodo@openssl.org>
Sat, 18 Mar 2000 15:18:27 +0000 (15:18 +0000)
apps/openssl.c
crypto/lhash/lhash.c
crypto/lhash/lhash.h
crypto/mem_dbg.c

index 934a1c1..a2a2630 100644 (file)
@@ -206,7 +206,7 @@ end:
 
        EVP_cleanup();
        ERR_free_strings();
-
+       
        CRYPTO_mem_leaks(bio_err);
        if (bio_err != NULL)
                {
index 512c8bc..7eb92a1 100644 (file)
@@ -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;
+       }
index 6f6eeb2..d315fd9 100644 (file)
@@ -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);
index 14770c0..a399485 100644 (file)
@@ -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);