- {
- char buf[1024];
- char *bufp = buf;
- APP_INFO *amip;
- int ami_cnt;
- struct tm *lcl = NULL;
- unsigned long ti;
-
- if(m->addr == (char *)l->bio)
- return;
-
- if (options & V_CRYPTO_MDEBUG_TIME)
- {
- lcl = localtime(&m->time);
-
- sprintf(bufp, "[%02d:%02d:%02d] ",
- lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
- bufp += strlen(bufp);
- }
-
- sprintf(bufp, "%5lu file=%s, line=%d, ",
- m->order,m->file,m->line);
- bufp += strlen(bufp);
-
- if (options & V_CRYPTO_MDEBUG_THREAD)
- {
- sprintf(bufp, "thread=%lu, ", m->thread);
- bufp += strlen(bufp);
- }
-
- sprintf(bufp, "number=%d, address=%08lX\n",
- m->num,(unsigned long)m->addr);
- bufp += strlen(bufp);
-
- BIO_puts(l->bio,buf);
-
- l->chunks++;
- l->bytes+=m->num;
-
- amip=m->app_info;
- ami_cnt=0;
- if (!amip)
- return;
- ti=amip->thread;
-
- do
- {
- int buf_len;
- int info_len;
-
- ami_cnt++;
- memset(buf,'>',ami_cnt);
- sprintf(buf + ami_cnt,
- " thread=%lu, file=%s, line=%d, info=\"",
- amip->thread, amip->file, amip->line);
- buf_len=strlen(buf);
- info_len=strlen(amip->info);
- if (128 - buf_len - 3 < info_len)
- {
- memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
- buf_len = 128 - 3;
- }
- else
- {
- strcpy(buf + buf_len, amip->info);
- buf_len = strlen(buf);
- }
- sprintf(buf + buf_len, "\"\n");
-
- BIO_puts(l->bio,buf);
-
- amip = amip->next;
- }
- while(amip && amip->thread == ti);
-
-#ifdef LEVITTE_DEBUG_MEM
- if (amip)
- {
- fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
- abort();
- }
-#endif
- }
-
-static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
-
-void CRYPTO_mem_leaks(BIO *b)
- {
- MEM_LEAK ml;
-
- if (mh == NULL && amih == NULL)
- return;
-
- MemCheck_off(); /* obtain MALLOC2 lock */
-
- ml.bio=b;
- ml.bytes=0;
- ml.chunks=0;
- if (mh != NULL)
- lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
- (char *)&ml);
- if (ml.chunks != 0)
- {
- BIO_printf(b,"%ld bytes leaked in %d chunks\n",
- ml.bytes,ml.chunks);
- }
- 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.)
- */
- int old_mh_mode;
-
- CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
-
- /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
- * which uses CRYPTO_is_mem_check_on */
- old_mh_mode = mh_mode;
- mh_mode = CRYPTO_MEM_CHECK_OFF;
-
- if (mh != NULL)
- {
- lh_free(mh);
- mh = NULL;
- }
- if (amih != NULL)
- {
- if (lh_num_items(amih) == 0)
- {
- lh_free(amih);
- amih = NULL;
- }
- }
-
- mh_mode = old_mh_mode;
- CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
- }
- MemCheck_on(); /* release MALLOC2 lock */
- }
-
-#ifndef OPENSSL_NO_FP_API
-void CRYPTO_mem_leaks_fp(FILE *fp)
- {
- BIO *b;
-
- if (mh == NULL) return;
- /* Need to turn off memory checking when allocated BIOs ... especially
- * as we're creating them at a time when we're trying to check we've not
- * left anything un-free()'d!! */
- MemCheck_off();
- b = BIO_new(BIO_s_file());
- MemCheck_on();
- if(!b) return;
- BIO_set_fp(b,fp,BIO_NOCLOSE);
- CRYPTO_mem_leaks(b);
- BIO_free(b);
- }
+{
+ char buf[1024];
+ char *bufp = buf;
+ APP_INFO *amip;
+ int ami_cnt;
+ struct tm *lcl = NULL;
+ /*
+ * Convert between CRYPTO_THREAD_ID (which could be anything at all) and
+ * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is
+ * but hopefully should give something sensible on most platforms
+ */
+ union {
+ CRYPTO_THREAD_ID tid;
+ unsigned long ltid;
+ } tid;
+ CRYPTO_THREAD_ID ti;
+
+#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
+
+ lcl = localtime(&m->time);
+ BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
+ lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
+ bufp += strlen(bufp);
+
+ BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
+ m->order, m->file, m->line);
+ bufp += strlen(bufp);
+
+ tid.ltid = 0;
+ tid.tid = m->threadid;
+ BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", tid.ltid);
+ bufp += strlen(bufp);
+
+ BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%p\n",
+ m->num, m->addr);
+ bufp += strlen(bufp);
+
+ BIO_puts(l->bio, buf);
+
+ l->chunks++;
+ l->bytes += m->num;
+
+ amip = m->app_info;
+ ami_cnt = 0;
+
+ if (amip) {
+ ti = amip->threadid;
+
+ do {
+ int buf_len;
+ int info_len;
+
+ ami_cnt++;
+ memset(buf, '>', ami_cnt);
+ tid.ltid = 0;
+ tid.tid = amip->threadid;
+ BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
+ " thread=%lu, file=%s, line=%d, info=\"",
+ tid.ltid, amip->file,
+ amip->line);
+ buf_len = strlen(buf);
+ info_len = strlen(amip->info);
+ if (128 - buf_len - 3 < info_len) {
+ memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
+ buf_len = 128 - 3;
+ } else {
+ OPENSSL_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
+ buf_len = strlen(buf);
+ }
+ BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
+
+ BIO_puts(l->bio, buf);
+
+ amip = amip->next;
+ }
+ while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti));
+ }
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+ {
+ size_t i;
+ char **strings = backtrace_symbols(m->array, m->array_siz);
+
+ for (i = 0; i < m->array_siz; i++)
+ fprintf(stderr, "##> %s\n", strings[i]);
+ free(strings);
+ }