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