diff --git a/tests/api.c b/tests/api.c index 16bd45f26..8fb42d866 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1051,7 +1051,6 @@ static int test_wolfSSL_SetMinVersion(void) const int versions[] = { WOLFSSL_TLSV1_3 }; #endif - AssertTrue(wolfSSL_Init()); #ifndef WOLFSSL_NO_TLS12 ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); #else @@ -1071,7 +1070,6 @@ static int test_wolfSSL_SetMinVersion(void) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - AssertTrue(wolfSSL_Cleanup()); #endif return failFlag; @@ -3100,9 +3098,6 @@ static void test_wolfSSL_PKCS8(void) bytes = (int)fread(buffer, 1, sizeof(buffer), f); fclose(f); - /* Note that wolfSSL_Init() or wolfCrypt_Init() has been called before these - * function calls */ - #ifndef NO_WOLFSSL_CLIENT #ifndef WOLFSSL_NO_TLS12 AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())); @@ -3210,7 +3205,6 @@ static int test_wolfSSL_CTX_SetMinVersion(void) failFlag = WOLFSSL_SUCCESS; - AssertTrue(wolfSSL_Init()); #ifndef WOLFSSL_NO_TLS12 ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); #else @@ -3228,7 +3222,6 @@ static int test_wolfSSL_CTX_SetMinVersion(void) printf(resultFmt, failFlag == WOLFSSL_SUCCESS ? passed : failed); wolfSSL_CTX_free(ctx); - AssertTrue(wolfSSL_Cleanup()); #endif return failFlag; @@ -3253,7 +3246,6 @@ static int test_wolfSSL_UseOCSPStapling(void) WOLFSSL_CTX* ctx; WOLFSSL* ssl; - wolfSSL_Init(); #ifndef NO_WOLFSSL_CLIENT #ifndef WOLFSSL_NO_TLS12 ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); @@ -3279,12 +3271,7 @@ static int test_wolfSSL_UseOCSPStapling(void) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - if(ret != WOLFSSL_SUCCESS){ - wolfSSL_Cleanup(); - return WOLFSSL_FAILURE; - } - - return wolfSSL_Cleanup(); + return ret; #else return WOLFSSL_SUCCESS; #endif @@ -3305,7 +3292,6 @@ static int test_wolfSSL_UseOCSPStaplingV2 (void) WOLFSSL_CTX* ctx; WOLFSSL* ssl; - wolfSSL_Init(); #ifndef NO_WOLFSSL_CLIENT #ifndef WOLFSSL_NO_TLS12 ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); @@ -3330,12 +3316,7 @@ static int test_wolfSSL_UseOCSPStaplingV2 (void) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); - if (ret != WOLFSSL_SUCCESS){ - wolfSSL_Cleanup(); - return WOLFSSL_FAILURE; - } - - return wolfSSL_Cleanup(); + return ret; #else return WOLFSSL_SUCCESS; #endif @@ -18941,7 +18922,6 @@ static void test_wolfSSL_OPENSSL_add_all_algorithms(void){ printf(testingFmt, "wolfSSL_OPENSSL_add_all_algorithms()"); AssertIntEQ(wolfSSL_OPENSSL_add_all_algorithms_noconf(),WOLFSSL_SUCCESS); - wolfSSL_Cleanup(); printf(resultFmt, passed); #endif @@ -20393,8 +20373,6 @@ void ApiTest(void) /* test the no op functions for compatibility */ test_no_op_functions(); - AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS); - /* wolfCrypt ASN tests */ test_wc_GetPkcs8TraditionalOffset(); @@ -20604,6 +20582,8 @@ void ApiTest(void) AssertIntEQ(test_ForceZero(), 0); + AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS); + printf(" End API Tests\n"); } diff --git a/tests/srp.c b/tests/srp.c index 529fbddc3..82c8bb791 100644 --- a/tests/srp.c +++ b/tests/srp.c @@ -817,6 +817,7 @@ static void test_SrpKeyGenFunc_cb(void) void SrpTest(void) { #if defined(WOLFCRYPT_HAVE_SRP) && defined(WOLFSSL_SHA512) + wolfCrypt_Init(); test_SrpInit(); test_SrpSetUsername(); test_SrpSetParams(); @@ -825,5 +826,6 @@ void SrpTest(void) test_SrpComputeKey(); test_SrpGetProofAndVerify(); test_SrpKeyGenFunc_cb(); + wolfCrypt_Cleanup(); #endif } diff --git a/wolfssl/wolfcrypt/mem_track.h b/wolfssl/wolfcrypt/mem_track.h index d964aadae..477245444 100644 --- a/wolfssl/wolfcrypt/mem_track.h +++ b/wolfssl/wolfcrypt/mem_track.h @@ -62,30 +62,62 @@ #include "wolfssl/wolfcrypt/logging.h" + #if defined(WOLFSSL_TRACK_MEMORY) + #define DO_MEM_STATS + #if defined(__linux__) || defined(__MACH__) + #define DO_MEM_LIST + #endif + #endif + + typedef struct memoryStats { - size_t totalAllocs; /* number of allocations */ - size_t totalDeallocs; /* number of deallocations */ - size_t totalBytes; /* total number of bytes allocated */ - size_t peakBytes; /* concurrent max bytes */ - size_t currentBytes; /* total current bytes in use */ + long totalAllocs; /* number of allocations */ + long totalDeallocs; /* number of deallocations */ + long totalBytes; /* total number of bytes allocated */ + long peakBytes; /* concurrent max bytes */ + long currentBytes; /* total current bytes in use */ } memoryStats; typedef struct memHint { size_t thisSize; /* size of this memory */ + + #ifdef DO_MEM_LIST + struct memHint* next; + struct memHint* prev; + #ifdef WOLFSSL_DEBUG_MEMORY + const char* func; + unsigned int line; + #endif + #endif void* thisMemory; /* actual memory for user */ } memHint; typedef struct memoryTrack { union { memHint hint; - byte alignit[16]; /* make sure we have strong alignment */ + byte alignit[sizeof(memHint) + (16-1 & ~(16-1))]; /* make sure we have strong alignment */ } u; } memoryTrack; - #if defined(WOLFSSL_TRACK_MEMORY) - #define DO_MEM_STATS - static memoryStats ourMemStats; +#ifdef DO_MEM_LIST + /* track allocations and report at end */ + typedef struct memoryList { + memHint* head; + memHint* tail; + uint32_t count; + } memoryList; +#endif + +#if defined(WOLFSSL_TRACK_MEMORY) + static memoryStats ourMemStats; + + #ifdef DO_MEM_LIST + #include + static memoryList ourMemList; + static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER; #endif +#endif + /* if defined to not using inline then declare function prototypes */ #ifdef NO_INLINE @@ -112,6 +144,7 @@ #endif { memoryTrack* mt; + memHint* header; if (sz == 0) return NULL; @@ -120,22 +153,50 @@ if (mt == NULL) return NULL; - mt->u.hint.thisSize = sz; - mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack); + header = &mt->u.hint; + header->thisSize = sz; + header->thisMemory = (byte*)mt + sizeof(memoryTrack); -#ifdef WOLFSSL_DEBUG_MEMORY_PRINT - printf("Alloc: %p -> %u at %s:%d\n", mt->u.hint.thisMemory, (word32)sz, func, line); -#endif + #ifdef WOLFSSL_DEBUG_MEMORY + #ifdef WOLFSSL_DEBUG_MEMORY_PRINT + printf("Alloc: %p -> %u at %s:%d\n", header->thisMemory, (word32)sz, func, line); + #else + (void)func; + (void)line; + #endif + #endif -#ifdef DO_MEM_STATS + #ifdef DO_MEM_STATS ourMemStats.totalAllocs++; ourMemStats.totalBytes += sz; ourMemStats.currentBytes += sz; if (ourMemStats.currentBytes > ourMemStats.peakBytes) ourMemStats.peakBytes = ourMemStats.currentBytes; -#endif + #endif + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) { + #ifdef WOLFSSL_DEBUG_MEMORY + header->func = func; + header->line = line; + #endif - return mt->u.hint.thisMemory; + /* Setup event */ + header->next = NULL; + if (ourMemList.tail == NULL) { + ourMemList.head = header; + } + else { + ourMemList.tail->next = header; + header->prev = ourMemList.tail; + } + ourMemList.tail = header; /* add to the end either way */ + ourMemList.count++; + + pthread_mutex_unlock(&memLock); + } + #endif + + return header->thisMemory; } @@ -146,21 +207,61 @@ #endif { memoryTrack* mt; + memHint* header; + size_t sz; if (ptr == NULL) { return; } - mt = (memoryTrack*)ptr; - --mt; /* same as minus sizeof(memoryTrack), removes header */ + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + sz = header->thisSize; -#ifdef DO_MEM_STATS - ourMemStats.currentBytes -= mt->u.hint.thisSize; - ourMemStats.totalDeallocs++; -#endif + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + #ifdef DO_MEM_STATS + ourMemStats.currentBytes -= header->thisSize; + ourMemStats.totalDeallocs++; + #endif + + #ifdef DO_MEM_LIST + if (header == ourMemList.head && header == ourMemList.tail) { + ourMemList.head = NULL; + ourMemList.tail = NULL; + } + else if (header == ourMemList.head) { + ourMemList.head = header->next; + ourMemList.head->prev = NULL; + } + else if (header == ourMemList.tail) { + ourMemList.tail = header->prev; + ourMemList.tail->next = NULL; + } + else { + memHint* next = header->next; + memHint* prev = header->prev; + if (next) + next->prev = prev; + if (prev) + prev->next = next; + } + ourMemList.count--; + + pthread_mutex_unlock(&memLock); + } + #endif + +#ifdef WOLFSSL_DEBUG_MEMORY #ifdef WOLFSSL_DEBUG_MEMORY_PRINT - printf("Free: %p -> %u at %s:%d\n", ptr, (word32)mt->u.hint.thisSize, func, line); + printf("Free: %p -> %u at %s:%d\n", ptr, (word32)sz, func, line); +#else + (void)func; + (void)line; +#endif #endif free(mt); @@ -181,11 +282,14 @@ if (ptr) { /* if realloc is bigger, don't overread old ptr */ - memoryTrack* mt = (memoryTrack*)ptr; - --mt; /* same as minus sizeof(memoryTrack), removes header */ + memoryTrack* mt; + memHint* header; - if (mt->u.hint.thisSize < sz) - sz = mt->u.hint.thisSize; + mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack)); + header = &mt->u.hint; + + if (header->thisSize < sz) + sz = header->thisSize; } if (ret && ptr) @@ -211,6 +315,11 @@ return ret; } + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + #ifdef DO_MEM_STATS ourMemStats.totalAllocs = 0; ourMemStats.totalDeallocs = 0; @@ -218,23 +327,52 @@ ourMemStats.peakBytes = 0; ourMemStats.currentBytes = 0; #endif + + #ifdef DO_MEM_LIST + XMEMSET(&ourMemList, 0, sizeof(ourMemList)); + + pthread_mutex_unlock(&memLock); + } + #endif return ret; } STATIC WC_INLINE void ShowMemoryTracker(void) { + #ifdef DO_MEM_LIST + if (pthread_mutex_lock(&memLock) == 0) + { + #endif + #ifdef DO_MEM_STATS - printf("total Allocs = %9lu\n", - (unsigned long)ourMemStats.totalAllocs); - printf("total Deallocs = %9lu\n", - (unsigned long)ourMemStats.totalDeallocs); - printf("total Bytes = %9lu\n", - (unsigned long)ourMemStats.totalBytes); - printf("peak Bytes = %9lu\n", - (unsigned long)ourMemStats.peakBytes); - printf("current Bytes = %9lu\n", - (unsigned long)ourMemStats.currentBytes); + printf("total Allocs = %9ld\n", ourMemStats.totalAllocs); + printf("total Deallocs = %9ld\n", ourMemStats.totalDeallocs); + printf("total Bytes = %9ld\n", ourMemStats.totalBytes); + printf("peak Bytes = %9ld\n", ourMemStats.peakBytes); + printf("current Bytes = %9ld\n", ourMemStats.currentBytes); + #endif + + #ifdef DO_MEM_LIST + if (ourMemList.count > 0) { + /* print list of allocations */ + memHint* header; + for (header = ourMemList.head; header != NULL; header = header->next) { + printf("Leak: Ptr %p, Size %u" + #ifdef WOLFSSL_DEBUG_MEMORY + ", Func %s, Line %d" + #endif + "\n", + (byte*)header + sizeof(memHint), (unsigned int)header->thisSize + #ifdef WOLFSSL_DEBUG_MEMORY + , header->func, header->line + #endif + ); + } + } + + pthread_mutex_unlock(&memLock); + } #endif }