Home | History | Annotate | Download | only in crypto
      1 /* crypto/mem_dbg.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.]
     57  */
     58 
     59 #include <stdio.h>
     60 #include <stdlib.h>
     61 #include <time.h>
     62 #include "cryptlib.h"
     63 #include <openssl/crypto.h>
     64 #include <openssl/buffer.h>
     65 #include <openssl/bio.h>
     66 #include <openssl/lhash.h>
     67 
     68 static int mh_mode=CRYPTO_MEM_CHECK_OFF;
     69 /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
     70  * when the application asks for it (usually after library initialisation
     71  * for which no book-keeping is desired).
     72  *
     73  * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
     74  * thinks that certain allocations should not be checked (e.g. the data
     75  * structures used for memory checking).  It is not suitable as an initial
     76  * state: the library will unexpectedly enable memory checking when it
     77  * executes one of those sections that want to disable checking
     78  * temporarily.
     79  *
     80  * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
     81  */
     82 
     83 static unsigned long order = 0; /* number of memory requests */
     84 static LHASH *mh=NULL; /* hash-table of memory requests (address as key);
     85                         * access requires MALLOC2 lock */
     86 
     87 
     88 typedef struct app_mem_info_st
     89 /* For application-defined information (static C-string `info')
     90  * to be displayed in memory leak list.
     91  * Each thread has its own stack.  For applications, there is
     92  *   CRYPTO_push_info("...")     to push an entry,
     93  *   CRYPTO_pop_info()           to pop an entry,
     94  *   CRYPTO_remove_all_info()    to pop all entries.
     95  */
     96 	{
     97 	unsigned long thread;
     98 	const char *file;
     99 	int line;
    100 	const char *info;
    101 	struct app_mem_info_st *next; /* tail of thread's stack */
    102 	int references;
    103 	} APP_INFO;
    104 
    105 static void app_info_free(APP_INFO *);
    106 
    107 static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
    108                           * that are at the top of their thread's stack
    109                           * (with `thread' as key);
    110                           * access requires MALLOC2 lock */
    111 
    112 typedef struct mem_st
    113 /* memory-block description */
    114 	{
    115 	void *addr;
    116 	int num;
    117 	const char *file;
    118 	int line;
    119 	unsigned long thread;
    120 	unsigned long order;
    121 	time_t time;
    122 	APP_INFO *app_info;
    123 	} MEM;
    124 
    125 static long options =             /* extra information to be recorded */
    126 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
    127 	V_CRYPTO_MDEBUG_TIME |
    128 #endif
    129 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
    130 	V_CRYPTO_MDEBUG_THREAD |
    131 #endif
    132 	0;
    133 
    134 
    135 static unsigned int num_disable = 0; /* num_disable > 0
    136                                       *     iff
    137                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
    138                                       */
    139 static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0.
    140                                             * CRYPTO_LOCK_MALLOC2 is locked
    141                                             * exactly in this case (by the
    142                                             * thread named in disabling_thread).
    143                                             */
    144 
    145 static void app_info_free(APP_INFO *inf)
    146 	{
    147 	if (--(inf->references) <= 0)
    148 		{
    149 		if (inf->next != NULL)
    150 			{
    151 			app_info_free(inf->next);
    152 			}
    153 		OPENSSL_free(inf);
    154 		}
    155 	}
    156 
    157 int CRYPTO_mem_ctrl(int mode)
    158 	{
    159 	int ret=mh_mode;
    160 
    161 	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
    162 	switch (mode)
    163 		{
    164 	/* for applications (not to be called while multiple threads
    165 	 * use the library): */
    166 	case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
    167 		mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
    168 		num_disable = 0;
    169 		break;
    170 	case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
    171 		mh_mode = 0;
    172 		num_disable = 0; /* should be true *before* MemCheck_stop is used,
    173 		                    or there'll be a lot of confusion */
    174 		break;
    175 
    176 	/* switch off temporarily (for library-internal use): */
    177 	case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
    178 		if (mh_mode & CRYPTO_MEM_CHECK_ON)
    179 			{
    180 			if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */
    181 				{
    182 				/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
    183 				 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
    184 				 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
    185 				 * it because we block entry to this function).
    186 				 * Give them a chance, first, and then claim the locks in
    187 				 * appropriate order (long-time lock first).
    188 				 */
    189 				CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
    190 				/* Note that after we have waited for CRYPTO_LOCK_MALLOC2
    191 				 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
    192 				 * "case" and "if" branch because MemCheck_start and
    193 				 * MemCheck_stop may never be used while there are multiple
    194 				 * OpenSSL threads. */
    195 				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
    196 				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
    197 				mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
    198 				disabling_thread=CRYPTO_thread_id();
    199 				}
    200 			num_disable++;
    201 			}
    202 		break;
    203 	case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
    204 		if (mh_mode & CRYPTO_MEM_CHECK_ON)
    205 			{
    206 			if (num_disable) /* always true, or something is going wrong */
    207 				{
    208 				num_disable--;
    209 				if (num_disable == 0)
    210 					{
    211 					mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
    212 					CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
    213 					}
    214 				}
    215 			}
    216 		break;
    217 
    218 	default:
    219 		break;
    220 		}
    221 	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
    222 	return(ret);
    223 	}
    224 
    225 int CRYPTO_is_mem_check_on(void)
    226 	{
    227 	int ret = 0;
    228 
    229 	if (mh_mode & CRYPTO_MEM_CHECK_ON)
    230 		{
    231 		CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
    232 
    233 		ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
    234 			|| (disabling_thread != CRYPTO_thread_id());
    235 
    236 		CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
    237 		}
    238 	return(ret);
    239 	}
    240 
    241 
    242 void CRYPTO_dbg_set_options(long bits)
    243 	{
    244 	options = bits;
    245 	}
    246 
    247 long CRYPTO_dbg_get_options(void)
    248 	{
    249 	return options;
    250 	}
    251 
    252 /* static int mem_cmp(MEM *a, MEM *b) */
    253 static int mem_cmp(const void *a_void, const void *b_void)
    254 	{
    255 #ifdef _WIN64
    256 	const char *a=(const char *)((const MEM *)a_void)->addr,
    257 		   *b=(const char *)((const MEM *)b_void)->addr;
    258 	if (a==b)	return 0;
    259 	else if (a>b)	return 1;
    260 	else		return -1;
    261 #else
    262 	return((const char *)((const MEM *)a_void)->addr
    263 		- (const char *)((const MEM *)b_void)->addr);
    264 #endif
    265 	}
    266 
    267 /* static unsigned long mem_hash(MEM *a) */
    268 static unsigned long mem_hash(const void *a_void)
    269 	{
    270 	unsigned long ret;
    271 
    272 	ret=(unsigned long)((const MEM *)a_void)->addr;
    273 
    274 	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
    275 	return(ret);
    276 	}
    277 
    278 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
    279 static int app_info_cmp(const void *a_void, const void *b_void)
    280 	{
    281 	return(((const APP_INFO *)a_void)->thread
    282 		!= ((const APP_INFO *)b_void)->thread);
    283 	}
    284 
    285 /* static unsigned long app_info_hash(APP_INFO *a) */
    286 static unsigned long app_info_hash(const void *a_void)
    287 	{
    288 	unsigned long ret;
    289 
    290 	ret=(unsigned long)((const APP_INFO *)a_void)->thread;
    291 
    292 	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
    293 	return(ret);
    294 	}
    295 
    296 static APP_INFO *pop_info(void)
    297 	{
    298 	APP_INFO tmp;
    299 	APP_INFO *ret = NULL;
    300 
    301 	if (amih != NULL)
    302 		{
    303 		tmp.thread=CRYPTO_thread_id();
    304 		if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
    305 			{
    306 			APP_INFO *next=ret->next;
    307 
    308 			if (next != NULL)
    309 				{
    310 				next->references++;
    311 				lh_insert(amih,(char *)next);
    312 				}
    313 #ifdef LEVITTE_DEBUG_MEM
    314 			if (ret->thread != tmp.thread)
    315 				{
    316 				fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
    317 					ret->thread, tmp.thread);
    318 				abort();
    319 				}
    320 #endif
    321 			if (--(ret->references) <= 0)
    322 				{
    323 				ret->next = NULL;
    324 				if (next != NULL)
    325 					next->references--;
    326 				OPENSSL_free(ret);
    327 				}
    328 			}
    329 		}
    330 	return(ret);
    331 	}
    332 
    333 int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
    334 	{
    335 	APP_INFO *ami, *amim;
    336 	int ret=0;
    337 
    338 	if (is_MemCheck_on())
    339 		{
    340 		MemCheck_off(); /* obtain MALLOC2 lock */
    341 
    342 		if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
    343 			{
    344 			ret=0;
    345 			goto err;
    346 			}
    347 		if (amih == NULL)
    348 			{
    349 			if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
    350 				{
    351 				OPENSSL_free(ami);
    352 				ret=0;
    353 				goto err;
    354 				}
    355 			}
    356 
    357 		ami->thread=CRYPTO_thread_id();
    358 		ami->file=file;
    359 		ami->line=line;
    360 		ami->info=info;
    361 		ami->references=1;
    362 		ami->next=NULL;
    363 
    364 		if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
    365 			{
    366 #ifdef LEVITTE_DEBUG_MEM
    367 			if (ami->thread != amim->thread)
    368 				{
    369 				fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
    370 					amim->thread, ami->thread);
    371 				abort();
    372 				}
    373 #endif
    374 			ami->next=amim;
    375 			}
    376  err:
    377 		MemCheck_on(); /* release MALLOC2 lock */
    378 		}
    379 
    380 	return(ret);
    381 	}
    382 
    383 int CRYPTO_dbg_pop_info(void)
    384 	{
    385 	int ret=0;
    386 
    387 	if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
    388 		{
    389 		MemCheck_off(); /* obtain MALLOC2 lock */
    390 
    391 		ret=(pop_info() != NULL);
    392 
    393 		MemCheck_on(); /* release MALLOC2 lock */
    394 		}
    395 	return(ret);
    396 	}
    397 
    398 int CRYPTO_dbg_remove_all_info(void)
    399 	{
    400 	int ret=0;
    401 
    402 	if (is_MemCheck_on()) /* _must_ be true */
    403 		{
    404 		MemCheck_off(); /* obtain MALLOC2 lock */
    405 
    406 		while(pop_info() != NULL)
    407 			ret++;
    408 
    409 		MemCheck_on(); /* release MALLOC2 lock */
    410 		}
    411 	return(ret);
    412 	}
    413 
    414 
    415 static unsigned long break_order_num=0;
    416 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
    417 	int before_p)
    418 	{
    419 	MEM *m,*mm;
    420 	APP_INFO tmp,*amim;
    421 
    422 	switch(before_p & 127)
    423 		{
    424 	case 0:
    425 		break;
    426 	case 1:
    427 		if (addr == NULL)
    428 			break;
    429 
    430 		if (is_MemCheck_on())
    431 			{
    432 			MemCheck_off(); /* make sure we hold MALLOC2 lock */
    433 			if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
    434 				{
    435 				OPENSSL_free(addr);
    436 				MemCheck_on(); /* release MALLOC2 lock
    437 				                * if num_disabled drops to 0 */
    438 				return;
    439 				}
    440 			if (mh == NULL)
    441 				{
    442 				if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
    443 					{
    444 					OPENSSL_free(addr);
    445 					OPENSSL_free(m);
    446 					addr=NULL;
    447 					goto err;
    448 					}
    449 				}
    450 
    451 			m->addr=addr;
    452 			m->file=file;
    453 			m->line=line;
    454 			m->num=num;
    455 			if (options & V_CRYPTO_MDEBUG_THREAD)
    456 				m->thread=CRYPTO_thread_id();
    457 			else
    458 				m->thread=0;
    459 
    460 			if (order == break_order_num)
    461 				{
    462 				/* BREAK HERE */
    463 				m->order=order;
    464 				}
    465 			m->order=order++;
    466 #ifdef LEVITTE_DEBUG_MEM
    467 			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
    468 				m->order,
    469 				(before_p & 128) ? '*' : '+',
    470 				m->addr, m->num);
    471 #endif
    472 			if (options & V_CRYPTO_MDEBUG_TIME)
    473 				m->time=time(NULL);
    474 			else
    475 				m->time=0;
    476 
    477 			tmp.thread=CRYPTO_thread_id();
    478 			m->app_info=NULL;
    479 			if (amih != NULL
    480 				&& (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
    481 				{
    482 				m->app_info = amim;
    483 				amim->references++;
    484 				}
    485 
    486 			if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
    487 				{
    488 				/* Not good, but don't sweat it */
    489 				if (mm->app_info != NULL)
    490 					{
    491 					mm->app_info->references--;
    492 					}
    493 				OPENSSL_free(mm);
    494 				}
    495 		err:
    496 			MemCheck_on(); /* release MALLOC2 lock
    497 			                * if num_disabled drops to 0 */
    498 			}
    499 		break;
    500 		}
    501 	return;
    502 	}
    503 
    504 void CRYPTO_dbg_free(void *addr, int before_p)
    505 	{
    506 	MEM m,*mp;
    507 
    508 	switch(before_p)
    509 		{
    510 	case 0:
    511 		if (addr == NULL)
    512 			break;
    513 
    514 		if (is_MemCheck_on() && (mh != NULL))
    515 			{
    516 			MemCheck_off(); /* make sure we hold MALLOC2 lock */
    517 
    518 			m.addr=addr;
    519 			mp=(MEM *)lh_delete(mh,(char *)&m);
    520 			if (mp != NULL)
    521 				{
    522 #ifdef LEVITTE_DEBUG_MEM
    523 			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
    524 				mp->order, mp->addr, mp->num);
    525 #endif
    526 				if (mp->app_info != NULL)
    527 					app_info_free(mp->app_info);
    528 				OPENSSL_free(mp);
    529 				}
    530 
    531 			MemCheck_on(); /* release MALLOC2 lock
    532 			                * if num_disabled drops to 0 */
    533 			}
    534 		break;
    535 	case 1:
    536 		break;
    537 		}
    538 	}
    539 
    540 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
    541 	const char *file, int line, int before_p)
    542 	{
    543 	MEM m,*mp;
    544 
    545 #ifdef LEVITTE_DEBUG_MEM
    546 	fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
    547 		addr1, addr2, num, file, line, before_p);
    548 #endif
    549 
    550 	switch(before_p)
    551 		{
    552 	case 0:
    553 		break;
    554 	case 1:
    555 		if (addr2 == NULL)
    556 			break;
    557 
    558 		if (addr1 == NULL)
    559 			{
    560 			CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
    561 			break;
    562 			}
    563 
    564 		if (is_MemCheck_on())
    565 			{
    566 			MemCheck_off(); /* make sure we hold MALLOC2 lock */
    567 
    568 			m.addr=addr1;
    569 			mp=(MEM *)lh_delete(mh,(char *)&m);
    570 			if (mp != NULL)
    571 				{
    572 #ifdef LEVITTE_DEBUG_MEM
    573 				fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
    574 					mp->order,
    575 					mp->addr, mp->num,
    576 					addr2, num);
    577 #endif
    578 				mp->addr=addr2;
    579 				mp->num=num;
    580 				lh_insert(mh,(char *)mp);
    581 				}
    582 
    583 			MemCheck_on(); /* release MALLOC2 lock
    584 			                * if num_disabled drops to 0 */
    585 			}
    586 		break;
    587 		}
    588 	return;
    589 	}
    590 
    591 
    592 typedef struct mem_leak_st
    593 	{
    594 	BIO *bio;
    595 	int chunks;
    596 	long bytes;
    597 	} MEM_LEAK;
    598 
    599 static void print_leak(const MEM *m, MEM_LEAK *l)
    600 	{
    601 	char buf[1024];
    602 	char *bufp = buf;
    603 	APP_INFO *amip;
    604 	int ami_cnt;
    605 	struct tm *lcl = NULL;
    606 	unsigned long ti;
    607 
    608 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
    609 
    610 	if(m->addr == (char *)l->bio)
    611 	    return;
    612 
    613 	if (options & V_CRYPTO_MDEBUG_TIME)
    614 		{
    615 		lcl = localtime(&m->time);
    616 
    617 		BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
    618 			lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
    619 		bufp += strlen(bufp);
    620 		}
    621 
    622 	BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
    623 		m->order,m->file,m->line);
    624 	bufp += strlen(bufp);
    625 
    626 	if (options & V_CRYPTO_MDEBUG_THREAD)
    627 		{
    628 		BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread);
    629 		bufp += strlen(bufp);
    630 		}
    631 
    632 	BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
    633 		m->num,(unsigned long)m->addr);
    634 	bufp += strlen(bufp);
    635 
    636 	BIO_puts(l->bio,buf);
    637 
    638 	l->chunks++;
    639 	l->bytes+=m->num;
    640 
    641 	amip=m->app_info;
    642 	ami_cnt=0;
    643 	if (!amip)
    644 		return;
    645 	ti=amip->thread;
    646 
    647 	do
    648 		{
    649 		int buf_len;
    650 		int info_len;
    651 
    652 		ami_cnt++;
    653 		memset(buf,'>',ami_cnt);
    654 		BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
    655 			" thread=%lu, file=%s, line=%d, info=\"",
    656 			amip->thread, amip->file, amip->line);
    657 		buf_len=strlen(buf);
    658 		info_len=strlen(amip->info);
    659 		if (128 - buf_len - 3 < info_len)
    660 			{
    661 			memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
    662 			buf_len = 128 - 3;
    663 			}
    664 		else
    665 			{
    666 			BUF_strlcpy(buf + buf_len, amip->info,
    667 				    sizeof buf - buf_len);
    668 			buf_len = strlen(buf);
    669 			}
    670 		BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
    671 
    672 		BIO_puts(l->bio,buf);
    673 
    674 		amip = amip->next;
    675 		}
    676 	while(amip && amip->thread == ti);
    677 
    678 #ifdef LEVITTE_DEBUG_MEM
    679 	if (amip)
    680 		{
    681 		fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
    682 		abort();
    683 		}
    684 #endif
    685 	}
    686 
    687 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
    688 
    689 void CRYPTO_mem_leaks(BIO *b)
    690 	{
    691 	MEM_LEAK ml;
    692 
    693 	if (mh == NULL && amih == NULL)
    694 		return;
    695 
    696 	MemCheck_off(); /* obtain MALLOC2 lock */
    697 
    698 	ml.bio=b;
    699 	ml.bytes=0;
    700 	ml.chunks=0;
    701 	if (mh != NULL)
    702 		lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
    703 				(char *)&ml);
    704 	if (ml.chunks != 0)
    705 		{
    706 		BIO_printf(b,"%ld bytes leaked in %d chunks\n",
    707 			   ml.bytes,ml.chunks);
    708 		}
    709 	else
    710 		{
    711 		/* Make sure that, if we found no leaks, memory-leak debugging itself
    712 		 * does not introduce memory leaks (which might irritate
    713 		 * external debugging tools).
    714 		 * (When someone enables leak checking, but does not call
    715 		 * this function, we declare it to be their fault.)
    716 		 *
    717 		 * XXX    This should be in CRYPTO_mem_leaks_cb,
    718 		 * and CRYPTO_mem_leaks should be implemented by
    719 		 * using CRYPTO_mem_leaks_cb.
    720 		 * (Also their should be a variant of lh_doall_arg
    721 		 * that takes a function pointer instead of a void *;
    722 		 * this would obviate the ugly and illegal
    723 		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
    724 		 * Otherwise the code police will come and get us.)
    725 		 */
    726 		int old_mh_mode;
    727 
    728 		CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
    729 
    730 		/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
    731 		 * which uses CRYPTO_is_mem_check_on */
    732 		old_mh_mode = mh_mode;
    733 		mh_mode = CRYPTO_MEM_CHECK_OFF;
    734 
    735 		if (mh != NULL)
    736 			{
    737 			lh_free(mh);
    738 			mh = NULL;
    739 			}
    740 		if (amih != NULL)
    741 			{
    742 			if (lh_num_items(amih) == 0)
    743 				{
    744 				lh_free(amih);
    745 				amih = NULL;
    746 				}
    747 			}
    748 
    749 		mh_mode = old_mh_mode;
    750 		CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
    751 		}
    752 	MemCheck_on(); /* release MALLOC2 lock */
    753 	}
    754 
    755 #ifndef OPENSSL_NO_FP_API
    756 void CRYPTO_mem_leaks_fp(FILE *fp)
    757 	{
    758 	BIO *b;
    759 
    760 	if (mh == NULL) return;
    761 	/* Need to turn off memory checking when allocated BIOs ... especially
    762 	 * as we're creating them at a time when we're trying to check we've not
    763 	 * left anything un-free()'d!! */
    764 	MemCheck_off();
    765 	b = BIO_new(BIO_s_file());
    766 	MemCheck_on();
    767 	if(!b) return;
    768 	BIO_set_fp(b,fp,BIO_NOCLOSE);
    769 	CRYPTO_mem_leaks(b);
    770 	BIO_free(b);
    771 	}
    772 #endif
    773 
    774 
    775 
    776 /* FIXME: We really don't allow much to the callback.  For example, it has
    777    no chance of reaching the info stack for the item it processes.  Should
    778    it really be this way?  -- Richard Levitte */
    779 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
    780  * If this code is restructured, remove the callback type if it is no longer
    781  * needed. -- Geoff Thorpe */
    782 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
    783 	{
    784 	(**cb)(m->order,m->file,m->line,m->num,m->addr);
    785 	}
    786 
    787 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
    788 
    789 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
    790 	{
    791 	if (mh == NULL) return;
    792 	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
    793 	lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
    794 	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
    795 	}
    796 
    797 void CRYPTO_malloc_debug_init(void)
    798 	{
    799 	CRYPTO_set_mem_debug_functions(
    800 		CRYPTO_dbg_malloc,
    801 		CRYPTO_dbg_realloc,
    802 		CRYPTO_dbg_free,
    803 		CRYPTO_dbg_set_options,
    804 		CRYPTO_dbg_get_options);
    805 	CRYPTO_set_mem_info_functions(
    806 		CRYPTO_dbg_push_info,
    807 		CRYPTO_dbg_pop_info,
    808 		CRYPTO_dbg_remove_all_info);
    809 	}
    810 
    811 char *CRYPTO_strdup(const char *str, const char *file, int line)
    812 	{
    813 	char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
    814 
    815 	strcpy(ret, str);
    816 	return ret;
    817 	}
    818