Index: openssl/crypto/mem_dbg.c |
=================================================================== |
--- openssl/crypto/mem_dbg.c (revision 105093) |
+++ openssl/crypto/mem_dbg.c (working copy) |
@@ -55,6 +55,59 @@ |
* copied and put under another distribution licence |
* [including the GNU Public Licence.] |
*/ |
+/* ==================================================================== |
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions |
+ * are met: |
+ * |
+ * 1. Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * |
+ * 2. Redistributions in binary form must reproduce the above copyright |
+ * notice, this list of conditions and the following disclaimer in |
+ * the documentation and/or other materials provided with the |
+ * distribution. |
+ * |
+ * 3. All advertising materials mentioning features or use of this |
+ * software must display the following acknowledgment: |
+ * "This product includes software developed by the OpenSSL Project |
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
+ * |
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
+ * endorse or promote products derived from this software without |
+ * prior written permission. For written permission, please contact |
+ * openssl-core@openssl.org. |
+ * |
+ * 5. Products derived from this software may not be called "OpenSSL" |
+ * nor may "OpenSSL" appear in their names without prior written |
+ * permission of the OpenSSL Project. |
+ * |
+ * 6. Redistributions of any form whatsoever must retain the following |
+ * acknowledgment: |
+ * "This product includes software developed by the OpenSSL Project |
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
+ * OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * ==================================================================== |
+ * |
+ * This product includes cryptographic software written by Eric Young |
+ * (eay@cryptsoft.com). This product includes software written by Tim |
+ * Hudson (tjh@cryptsoft.com). |
+ * |
+ */ |
#include <stdio.h> |
#include <stdlib.h> |
@@ -81,10 +134,13 @@ |
*/ |
static unsigned long order = 0; /* number of memory requests */ |
-static LHASH *mh=NULL; /* hash-table of memory requests (address as key); |
- * access requires MALLOC2 lock */ |
+DECLARE_LHASH_OF(MEM); |
+static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests |
+ * (address as key); access requires |
+ * MALLOC2 lock */ |
+ |
typedef struct app_mem_info_st |
/* For application-defined information (static C-string `info') |
* to be displayed in memory leak list. |
@@ -93,8 +149,8 @@ |
* CRYPTO_pop_info() to pop an entry, |
* CRYPTO_remove_all_info() to pop all entries. |
*/ |
- { |
- unsigned long thread; |
+ { |
+ CRYPTO_THREADID threadid; |
const char *file; |
int line; |
const char *info; |
@@ -104,10 +160,13 @@ |
static void app_info_free(APP_INFO *); |
-static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's |
- * that are at the top of their thread's stack |
- * (with `thread' as key); |
- * access requires MALLOC2 lock */ |
+DECLARE_LHASH_OF(APP_INFO); |
+static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those |
+ * app_mem_info_st's that are at |
+ * the top of their thread's |
+ * stack (with `thread' as key); |
+ * access requires MALLOC2 |
+ * lock */ |
typedef struct mem_st |
/* memory-block description */ |
@@ -116,7 +175,7 @@ |
int num; |
const char *file; |
int line; |
- unsigned long thread; |
+ CRYPTO_THREADID threadid; |
unsigned long order; |
time_t time; |
APP_INFO *app_info; |
@@ -136,12 +195,12 @@ |
* iff |
* mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) |
*/ |
-static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. |
- * CRYPTO_LOCK_MALLOC2 is locked |
- * exactly in this case (by the |
- * thread named in disabling_thread). |
- */ |
+/* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this |
+ * case (by the thread named in disabling_thread). |
+ */ |
+static CRYPTO_THREADID disabling_threadid; |
+ |
static void app_info_free(APP_INFO *inf) |
{ |
if (--(inf->references) <= 0) |
@@ -177,7 +236,9 @@ |
case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ |
if (mh_mode & CRYPTO_MEM_CHECK_ON) |
{ |
- if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */ |
+ CRYPTO_THREADID cur; |
+ CRYPTO_THREADID_current(&cur); |
+ if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */ |
{ |
/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while |
* we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if |
@@ -195,7 +256,7 @@ |
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); |
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; |
- disabling_thread=CRYPTO_thread_id(); |
+ CRYPTO_THREADID_cpy(&disabling_threadid, &cur); |
} |
num_disable++; |
} |
@@ -228,10 +289,12 @@ |
if (mh_mode & CRYPTO_MEM_CHECK_ON) |
{ |
+ CRYPTO_THREADID cur; |
+ CRYPTO_THREADID_current(&cur); |
CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); |
ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) |
- || (disabling_thread != CRYPTO_thread_id()); |
+ || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); |
CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); |
} |
@@ -249,49 +312,49 @@ |
return options; |
} |
-/* static int mem_cmp(MEM *a, MEM *b) */ |
-static int mem_cmp(const void *a_void, const void *b_void) |
+static int mem_cmp(const MEM *a, const MEM *b) |
{ |
#ifdef _WIN64 |
- const char *a=(const char *)((const MEM *)a_void)->addr, |
- *b=(const char *)((const MEM *)b_void)->addr; |
- if (a==b) return 0; |
- else if (a>b) return 1; |
+ const char *ap=(const char *)a->addr, |
+ *bp=(const char *)b->addr; |
+ if (ap==bp) return 0; |
+ else if (ap>bp) return 1; |
else return -1; |
#else |
- return((const char *)((const MEM *)a_void)->addr |
- - (const char *)((const MEM *)b_void)->addr); |
+ return (const char *)a->addr - (const char *)b->addr; |
#endif |
} |
+static IMPLEMENT_LHASH_COMP_FN(mem, MEM) |
-/* static unsigned long mem_hash(MEM *a) */ |
-static unsigned long mem_hash(const void *a_void) |
+static unsigned long mem_hash(const MEM *a) |
{ |
unsigned long ret; |
- ret=(unsigned long)((const MEM *)a_void)->addr; |
+ ret=(unsigned long)a->addr; |
ret=ret*17851+(ret>>14)*7+(ret>>4)*251; |
return(ret); |
} |
+static IMPLEMENT_LHASH_HASH_FN(mem, MEM) |
/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ |
static int app_info_cmp(const void *a_void, const void *b_void) |
{ |
- return(((const APP_INFO *)a_void)->thread |
- != ((const APP_INFO *)b_void)->thread); |
+ return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid, |
+ &((const APP_INFO *)b_void)->threadid); |
} |
+static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO) |
-/* static unsigned long app_info_hash(APP_INFO *a) */ |
-static unsigned long app_info_hash(const void *a_void) |
+static unsigned long app_info_hash(const APP_INFO *a) |
{ |
unsigned long ret; |
- ret=(unsigned long)((const APP_INFO *)a_void)->thread; |
- |
+ ret = CRYPTO_THREADID_hash(&a->threadid); |
+ /* This is left in as a "who am I to question legacy?" measure */ |
ret=ret*17851+(ret>>14)*7+(ret>>4)*251; |
return(ret); |
} |
+static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO) |
static APP_INFO *pop_info(void) |
{ |
@@ -300,21 +363,22 @@ |
if (amih != NULL) |
{ |
- tmp.thread=CRYPTO_thread_id(); |
- if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) |
+ CRYPTO_THREADID_current(&tmp.threadid); |
+ if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL) |
{ |
APP_INFO *next=ret->next; |
if (next != NULL) |
{ |
next->references++; |
- lh_insert(amih,(char *)next); |
+ (void)lh_APP_INFO_insert(amih,next); |
} |
#ifdef LEVITTE_DEBUG_MEM |
- if (ret->thread != tmp.thread) |
+ if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) |
{ |
fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", |
- ret->thread, tmp.thread); |
+ CRYPTO_THREADID_hash(&ret->threadid), |
+ CRYPTO_THREADID_hash(&tmp.threadid)); |
abort(); |
} |
#endif |
@@ -330,7 +394,7 @@ |
return(ret); |
} |
-int CRYPTO_dbg_push_info(const char *info, const char *file, int line) |
+int CRYPTO_push_info_(const char *info, const char *file, int line) |
{ |
APP_INFO *ami, *amim; |
int ret=0; |
@@ -346,7 +410,7 @@ |
} |
if (amih == NULL) |
{ |
- if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL) |
+ if ((amih=lh_APP_INFO_new()) == NULL) |
{ |
OPENSSL_free(ami); |
ret=0; |
@@ -354,20 +418,21 @@ |
} |
} |
- ami->thread=CRYPTO_thread_id(); |
+ CRYPTO_THREADID_current(&ami->threadid); |
ami->file=file; |
ami->line=line; |
ami->info=info; |
ami->references=1; |
ami->next=NULL; |
- if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL) |
+ if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL) |
{ |
#ifdef LEVITTE_DEBUG_MEM |
- if (ami->thread != amim->thread) |
+ if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) |
{ |
fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", |
- amim->thread, ami->thread); |
+ CRYPTO_THREADID_hash(&amim->threadid), |
+ CRYPTO_THREADID_hash(&ami->threadid)); |
abort(); |
} |
#endif |
@@ -380,7 +445,7 @@ |
return(ret); |
} |
-int CRYPTO_dbg_pop_info(void) |
+int CRYPTO_pop_info(void) |
{ |
int ret=0; |
@@ -395,7 +460,7 @@ |
return(ret); |
} |
-int CRYPTO_dbg_remove_all_info(void) |
+int CRYPTO_remove_all_info(void) |
{ |
int ret=0; |
@@ -439,7 +504,7 @@ |
} |
if (mh == NULL) |
{ |
- if ((mh=lh_new(mem_hash, mem_cmp)) == NULL) |
+ if ((mh=lh_MEM_new()) == NULL) |
{ |
OPENSSL_free(addr); |
OPENSSL_free(m); |
@@ -453,9 +518,9 @@ |
m->line=line; |
m->num=num; |
if (options & V_CRYPTO_MDEBUG_THREAD) |
- m->thread=CRYPTO_thread_id(); |
+ CRYPTO_THREADID_current(&m->threadid); |
else |
- m->thread=0; |
+ memset(&m->threadid, 0, sizeof(m->threadid)); |
if (order == break_order_num) |
{ |
@@ -464,7 +529,7 @@ |
} |
m->order=order++; |
#ifdef LEVITTE_DEBUG_MEM |
- fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n", |
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", |
m->order, |
(before_p & 128) ? '*' : '+', |
m->addr, m->num); |
@@ -474,16 +539,16 @@ |
else |
m->time=0; |
- tmp.thread=CRYPTO_thread_id(); |
+ CRYPTO_THREADID_current(&tmp.threadid); |
m->app_info=NULL; |
if (amih != NULL |
- && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) |
+ && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL) |
{ |
m->app_info = amim; |
amim->references++; |
} |
- if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) |
+ if ((mm=lh_MEM_insert(mh, m)) != NULL) |
{ |
/* Not good, but don't sweat it */ |
if (mm->app_info != NULL) |
@@ -516,11 +581,11 @@ |
MemCheck_off(); /* make sure we hold MALLOC2 lock */ |
m.addr=addr; |
- mp=(MEM *)lh_delete(mh,(char *)&m); |
+ mp=lh_MEM_delete(mh,&m); |
if (mp != NULL) |
{ |
#ifdef LEVITTE_DEBUG_MEM |
- fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n", |
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", |
mp->order, mp->addr, mp->num); |
#endif |
if (mp->app_info != NULL) |
@@ -566,18 +631,18 @@ |
MemCheck_off(); /* make sure we hold MALLOC2 lock */ |
m.addr=addr1; |
- mp=(MEM *)lh_delete(mh,(char *)&m); |
+ mp=lh_MEM_delete(mh,&m); |
if (mp != NULL) |
{ |
#ifdef LEVITTE_DEBUG_MEM |
- fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n", |
+ fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", |
mp->order, |
mp->addr, mp->num, |
addr2, num); |
#endif |
mp->addr=addr2; |
mp->num=num; |
- lh_insert(mh,(char *)mp); |
+ (void)lh_MEM_insert(mh,mp); |
} |
MemCheck_on(); /* release MALLOC2 lock |
@@ -596,14 +661,14 @@ |
long bytes; |
} MEM_LEAK; |
-static void print_leak(const MEM *m, MEM_LEAK *l) |
+static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) |
{ |
char buf[1024]; |
char *bufp = buf; |
APP_INFO *amip; |
int ami_cnt; |
struct tm *lcl = NULL; |
- unsigned long ti; |
+ CRYPTO_THREADID ti; |
#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) |
@@ -625,7 +690,8 @@ |
if (options & V_CRYPTO_MDEBUG_THREAD) |
{ |
- BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread); |
+ BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", |
+ CRYPTO_THREADID_hash(&m->threadid)); |
bufp += strlen(bufp); |
} |
@@ -642,8 +708,8 @@ |
ami_cnt=0; |
if (!amip) |
return; |
- ti=amip->thread; |
- |
+ CRYPTO_THREADID_cpy(&ti, &amip->threadid); |
+ |
do |
{ |
int buf_len; |
@@ -653,7 +719,8 @@ |
memset(buf,'>',ami_cnt); |
BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, |
" thread=%lu, file=%s, line=%d, info=\"", |
- amip->thread, amip->file, amip->line); |
+ CRYPTO_THREADID_hash(&amip->threadid), amip->file, |
+ amip->line); |
buf_len=strlen(buf); |
info_len=strlen(amip->info); |
if (128 - buf_len - 3 < info_len) |
@@ -673,8 +740,8 @@ |
amip = amip->next; |
} |
- while(amip && amip->thread == ti); |
- |
+ while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); |
+ |
#ifdef LEVITTE_DEBUG_MEM |
if (amip) |
{ |
@@ -684,7 +751,7 @@ |
#endif |
} |
-static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *) |
+static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) |
void CRYPTO_mem_leaks(BIO *b) |
{ |
@@ -699,12 +766,15 @@ |
ml.bytes=0; |
ml.chunks=0; |
if (mh != NULL) |
- lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), |
- (char *)&ml); |
+ lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, |
+ &ml); |
if (ml.chunks != 0) |
{ |
BIO_printf(b,"%ld bytes leaked in %d chunks\n", |
ml.bytes,ml.chunks); |
+#ifdef CRYPTO_MDEBUG_ABORT |
+ abort(); |
+#endif |
} |
else |
{ |
@@ -717,7 +787,7 @@ |
* 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 |
+ * (Also there 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. |
@@ -734,14 +804,14 @@ |
if (mh != NULL) |
{ |
- lh_free(mh); |
+ lh_MEM_free(mh); |
mh = NULL; |
} |
if (amih != NULL) |
{ |
- if (lh_num_items(amih) == 0) |
+ if (lh_APP_INFO_num_items(amih) == 0) |
{ |
- lh_free(amih); |
+ lh_APP_INFO_free(amih); |
amih = NULL; |
} |
} |
@@ -779,39 +849,26 @@ |
/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h |
* If this code is restructured, remove the callback type if it is no longer |
* needed. -- Geoff Thorpe */ |
-static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb) |
+ |
+/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it |
+ * is a function pointer and conversion to void * is prohibited. Instead |
+ * pass its address |
+ */ |
+ |
+typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB; |
+ |
+static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb) |
{ |
- (**cb)(m->order,m->file,m->line,m->num,m->addr); |
+ (*cb)(m->order,m->file,m->line,m->num,m->addr); |
} |
-static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **) |
+static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB) |
void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) |
{ |
if (mh == NULL) return; |
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); |
- lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb); |
+ lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB, |
+ &cb); |
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); |
} |
- |
-void CRYPTO_malloc_debug_init(void) |
- { |
- CRYPTO_set_mem_debug_functions( |
- CRYPTO_dbg_malloc, |
- CRYPTO_dbg_realloc, |
- CRYPTO_dbg_free, |
- CRYPTO_dbg_set_options, |
- CRYPTO_dbg_get_options); |
- CRYPTO_set_mem_info_functions( |
- CRYPTO_dbg_push_info, |
- CRYPTO_dbg_pop_info, |
- CRYPTO_dbg_remove_all_info); |
- } |
- |
-char *CRYPTO_strdup(const char *str, const char *file, int line) |
- { |
- char *ret = CRYPTO_malloc(strlen(str)+1, file, line); |
- |
- strcpy(ret, str); |
- return ret; |
- } |