X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fmem_dbg.c;h=866c53e73a927e4fff3bdd381111bc80ef1c7f9c;hp=6068dcc806296531eeba073de55a717d3c939823;hb=27d7260075ba525c69e5b8e8ccb1b98010b56dd3;hpb=ed84dfab0092996323c206c9bde900e597eb8a00 diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index 6068dcc806..866c53e73a 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -108,7 +108,7 @@ static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's typedef struct mem_st /* memory-block description */ { - char *addr; + void *addr; int num; const char *file; int line; @@ -214,14 +214,14 @@ void CRYPTO_dbg_set_options(long bits) options = bits; } -long CRYPTO_dbg_get_options() +long CRYPTO_dbg_get_options(void) { return options; } static int mem_cmp(MEM *a, MEM *b) { - return(a->addr - b->addr); + return((char *)a->addr - (char *)b->addr); } static unsigned long mem_hash(MEM *a) @@ -257,7 +257,7 @@ static APP_INFO *pop_info() if (amih != NULL) { tmp.thread=CRYPTO_thread_id(); - if ((ret=(APP_INFO *)lh_delete(amih,(char *)&tmp)) != NULL) + if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) { APP_INFO *next=ret->next; @@ -279,7 +279,7 @@ static APP_INFO *pop_info() ret->next = NULL; if (next != NULL) next->references--; - Free(ret); + OPENSSL_free(ret); } } } @@ -295,7 +295,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) { MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ - if ((ami = (APP_INFO *)Malloc(sizeof(APP_INFO))) == NULL) + if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) { ret=0; goto err; @@ -304,7 +304,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) { if ((amih=lh_new(app_info_hash,app_info_cmp)) == NULL) { - Free(ami); + OPENSSL_free(ami); ret=0; goto err; } @@ -386,9 +386,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, if (is_MemCheck_on()) { MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ - if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL) + if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) { - Free(addr); + OPENSSL_free(addr); MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ return; } @@ -396,8 +396,8 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, { if ((mh=lh_new(mem_hash,mem_cmp)) == NULL) { - Free(addr); - Free(m); + OPENSSL_free(addr); + OPENSSL_free(m); addr=NULL; goto err; } @@ -445,7 +445,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, { mm->app_info->references--; } - Free(mm); + OPENSSL_free(mm); } err: MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ @@ -481,7 +481,7 @@ void CRYPTO_dbg_free(void *addr, int before_p) { mp->app_info->references--; } - Free(mp); + OPENSSL_free(mp); } MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ @@ -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); @@ -661,24 +696,6 @@ void CRYPTO_mem_leaks(BIO *b) #endif } -static void (*mem_cb)()=NULL; - -static void cb_leak(MEM *m, char *cb) - { - void (*mem_callback)()=(void (*)())cb; - mem_callback(m->order,m->file,m->line,m->num,m->addr); - } - -void CRYPTO_mem_leaks_cb(void (*cb)()) - { - if (mh == NULL) return; - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); - mem_cb=cb; - lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb); - mem_cb=NULL; - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); - } - #ifndef NO_FP_API void CRYPTO_mem_leaks_fp(FILE *fp) { @@ -693,3 +710,21 @@ void CRYPTO_mem_leaks_fp(FILE *fp) } #endif + + +/* FIXME: We really don't allow much to the callback. For example, it has + no chance of reaching the info stack for the item it processes. Should + it really be this way? -- Richard Levitte */ +static void cb_leak(MEM *m, + void (**cb)(unsigned long, const char *, int, int, void *)) + { + (**cb)(m->order,m->file,m->line,m->num,m->addr); + } + +void CRYPTO_mem_leaks_cb(void (*cb)(unsigned long, const char *, int, int, void *)) + { + if (mh == NULL) return; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); + lh_doall_arg(mh,(void (*)())cb_leak,(void *)&cb); + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); + }