Enhanced the --enable-memtrack option to keep list of pointers allocated and reports leaked memory at end. Cleanup of the wolfCrypt_Init and wolfCrypt_Cleanup calls in unit.test and SrpTest memory tracking feature.

This commit is contained in:
David Garske
2018-07-27 10:16:46 -07:00
parent 2c3475c1d6
commit 6ed6876b1f
3 changed files with 182 additions and 62 deletions

View File

@@ -1051,7 +1051,6 @@ static int test_wolfSSL_SetMinVersion(void)
const int versions[] = { WOLFSSL_TLSV1_3 }; const int versions[] = { WOLFSSL_TLSV1_3 };
#endif #endif
AssertTrue(wolfSSL_Init());
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
#else #else
@@ -1071,7 +1070,6 @@ static int test_wolfSSL_SetMinVersion(void)
wolfSSL_free(ssl); wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx); wolfSSL_CTX_free(ctx);
AssertTrue(wolfSSL_Cleanup());
#endif #endif
return failFlag; return failFlag;
@@ -3100,9 +3098,6 @@ static void test_wolfSSL_PKCS8(void)
bytes = (int)fread(buffer, 1, sizeof(buffer), f); bytes = (int)fread(buffer, 1, sizeof(buffer), f);
fclose(f); fclose(f);
/* Note that wolfSSL_Init() or wolfCrypt_Init() has been called before these
* function calls */
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())); AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
@@ -3210,7 +3205,6 @@ static int test_wolfSSL_CTX_SetMinVersion(void)
failFlag = WOLFSSL_SUCCESS; failFlag = WOLFSSL_SUCCESS;
AssertTrue(wolfSSL_Init());
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
#else #else
@@ -3228,7 +3222,6 @@ static int test_wolfSSL_CTX_SetMinVersion(void)
printf(resultFmt, failFlag == WOLFSSL_SUCCESS ? passed : failed); printf(resultFmt, failFlag == WOLFSSL_SUCCESS ? passed : failed);
wolfSSL_CTX_free(ctx); wolfSSL_CTX_free(ctx);
AssertTrue(wolfSSL_Cleanup());
#endif #endif
return failFlag; return failFlag;
@@ -3253,7 +3246,6 @@ static int test_wolfSSL_UseOCSPStapling(void)
WOLFSSL_CTX* ctx; WOLFSSL_CTX* ctx;
WOLFSSL* ssl; WOLFSSL* ssl;
wolfSSL_Init();
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
@@ -3279,12 +3271,7 @@ static int test_wolfSSL_UseOCSPStapling(void)
wolfSSL_free(ssl); wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx); wolfSSL_CTX_free(ctx);
if(ret != WOLFSSL_SUCCESS){ return ret;
wolfSSL_Cleanup();
return WOLFSSL_FAILURE;
}
return wolfSSL_Cleanup();
#else #else
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
#endif #endif
@@ -3305,7 +3292,6 @@ static int test_wolfSSL_UseOCSPStaplingV2 (void)
WOLFSSL_CTX* ctx; WOLFSSL_CTX* ctx;
WOLFSSL* ssl; WOLFSSL* ssl;
wolfSSL_Init();
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
@@ -3330,12 +3316,7 @@ static int test_wolfSSL_UseOCSPStaplingV2 (void)
wolfSSL_free(ssl); wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx); wolfSSL_CTX_free(ctx);
if (ret != WOLFSSL_SUCCESS){ return ret;
wolfSSL_Cleanup();
return WOLFSSL_FAILURE;
}
return wolfSSL_Cleanup();
#else #else
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
#endif #endif
@@ -18941,7 +18922,6 @@ static void test_wolfSSL_OPENSSL_add_all_algorithms(void){
printf(testingFmt, "wolfSSL_OPENSSL_add_all_algorithms()"); printf(testingFmt, "wolfSSL_OPENSSL_add_all_algorithms()");
AssertIntEQ(wolfSSL_OPENSSL_add_all_algorithms_noconf(),WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_OPENSSL_add_all_algorithms_noconf(),WOLFSSL_SUCCESS);
wolfSSL_Cleanup();
printf(resultFmt, passed); printf(resultFmt, passed);
#endif #endif
@@ -20393,8 +20373,6 @@ void ApiTest(void)
/* test the no op functions for compatibility */ /* test the no op functions for compatibility */
test_no_op_functions(); test_no_op_functions();
AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS);
/* wolfCrypt ASN tests */ /* wolfCrypt ASN tests */
test_wc_GetPkcs8TraditionalOffset(); test_wc_GetPkcs8TraditionalOffset();
@@ -20604,6 +20582,8 @@ void ApiTest(void)
AssertIntEQ(test_ForceZero(), 0); AssertIntEQ(test_ForceZero(), 0);
AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS);
printf(" End API Tests\n"); printf(" End API Tests\n");
} }

View File

@@ -817,6 +817,7 @@ static void test_SrpKeyGenFunc_cb(void)
void SrpTest(void) void SrpTest(void)
{ {
#if defined(WOLFCRYPT_HAVE_SRP) && defined(WOLFSSL_SHA512) #if defined(WOLFCRYPT_HAVE_SRP) && defined(WOLFSSL_SHA512)
wolfCrypt_Init();
test_SrpInit(); test_SrpInit();
test_SrpSetUsername(); test_SrpSetUsername();
test_SrpSetParams(); test_SrpSetParams();
@@ -825,5 +826,6 @@ void SrpTest(void)
test_SrpComputeKey(); test_SrpComputeKey();
test_SrpGetProofAndVerify(); test_SrpGetProofAndVerify();
test_SrpKeyGenFunc_cb(); test_SrpKeyGenFunc_cb();
wolfCrypt_Cleanup();
#endif #endif
} }

View File

@@ -62,30 +62,62 @@
#include "wolfssl/wolfcrypt/logging.h" #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 { typedef struct memoryStats {
size_t totalAllocs; /* number of allocations */ long totalAllocs; /* number of allocations */
size_t totalDeallocs; /* number of deallocations */ long totalDeallocs; /* number of deallocations */
size_t totalBytes; /* total number of bytes allocated */ long totalBytes; /* total number of bytes allocated */
size_t peakBytes; /* concurrent max bytes */ long peakBytes; /* concurrent max bytes */
size_t currentBytes; /* total current bytes in use */ long currentBytes; /* total current bytes in use */
} memoryStats; } memoryStats;
typedef struct memHint { typedef struct memHint {
size_t thisSize; /* size of this memory */ 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 */ void* thisMemory; /* actual memory for user */
} memHint; } memHint;
typedef struct memoryTrack { typedef struct memoryTrack {
union { union {
memHint hint; 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; } u;
} memoryTrack; } memoryTrack;
#if defined(WOLFSSL_TRACK_MEMORY) #ifdef DO_MEM_LIST
#define DO_MEM_STATS /* track allocations and report at end */
static memoryStats ourMemStats; 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 <pthread.h>
static memoryList ourMemList;
static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER;
#endif #endif
#endif
/* if defined to not using inline then declare function prototypes */ /* if defined to not using inline then declare function prototypes */
#ifdef NO_INLINE #ifdef NO_INLINE
@@ -112,6 +144,7 @@
#endif #endif
{ {
memoryTrack* mt; memoryTrack* mt;
memHint* header;
if (sz == 0) if (sz == 0)
return NULL; return NULL;
@@ -120,22 +153,50 @@
if (mt == NULL) if (mt == NULL)
return NULL; return NULL;
mt->u.hint.thisSize = sz; header = &mt->u.hint;
mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack); header->thisSize = sz;
header->thisMemory = (byte*)mt + sizeof(memoryTrack);
#ifdef WOLFSSL_DEBUG_MEMORY_PRINT #ifdef WOLFSSL_DEBUG_MEMORY
printf("Alloc: %p -> %u at %s:%d\n", mt->u.hint.thisMemory, (word32)sz, func, line); #ifdef WOLFSSL_DEBUG_MEMORY_PRINT
#endif 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.totalAllocs++;
ourMemStats.totalBytes += sz; ourMemStats.totalBytes += sz;
ourMemStats.currentBytes += sz; ourMemStats.currentBytes += sz;
if (ourMemStats.currentBytes > ourMemStats.peakBytes) if (ourMemStats.currentBytes > ourMemStats.peakBytes)
ourMemStats.peakBytes = ourMemStats.currentBytes; 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 #endif
{ {
memoryTrack* mt; memoryTrack* mt;
memHint* header;
size_t sz;
if (ptr == NULL) { if (ptr == NULL) {
return; return;
} }
mt = (memoryTrack*)ptr; mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));
--mt; /* same as minus sizeof(memoryTrack), removes header */ header = &mt->u.hint;
sz = header->thisSize;
#ifdef DO_MEM_STATS #ifdef DO_MEM_LIST
ourMemStats.currentBytes -= mt->u.hint.thisSize; if (pthread_mutex_lock(&memLock) == 0)
ourMemStats.totalDeallocs++; {
#endif #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 #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 #endif
free(mt); free(mt);
@@ -181,11 +282,14 @@
if (ptr) { if (ptr) {
/* if realloc is bigger, don't overread old ptr */ /* if realloc is bigger, don't overread old ptr */
memoryTrack* mt = (memoryTrack*)ptr; memoryTrack* mt;
--mt; /* same as minus sizeof(memoryTrack), removes header */ memHint* header;
if (mt->u.hint.thisSize < sz) mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));
sz = mt->u.hint.thisSize; header = &mt->u.hint;
if (header->thisSize < sz)
sz = header->thisSize;
} }
if (ret && ptr) if (ret && ptr)
@@ -211,6 +315,11 @@
return ret; return ret;
} }
#ifdef DO_MEM_LIST
if (pthread_mutex_lock(&memLock) == 0)
{
#endif
#ifdef DO_MEM_STATS #ifdef DO_MEM_STATS
ourMemStats.totalAllocs = 0; ourMemStats.totalAllocs = 0;
ourMemStats.totalDeallocs = 0; ourMemStats.totalDeallocs = 0;
@@ -218,23 +327,52 @@
ourMemStats.peakBytes = 0; ourMemStats.peakBytes = 0;
ourMemStats.currentBytes = 0; ourMemStats.currentBytes = 0;
#endif #endif
#ifdef DO_MEM_LIST
XMEMSET(&ourMemList, 0, sizeof(ourMemList));
pthread_mutex_unlock(&memLock);
}
#endif
return ret; return ret;
} }
STATIC WC_INLINE void ShowMemoryTracker(void) STATIC WC_INLINE void ShowMemoryTracker(void)
{ {
#ifdef DO_MEM_LIST
if (pthread_mutex_lock(&memLock) == 0)
{
#endif
#ifdef DO_MEM_STATS #ifdef DO_MEM_STATS
printf("total Allocs = %9lu\n", printf("total Allocs = %9ld\n", ourMemStats.totalAllocs);
(unsigned long)ourMemStats.totalAllocs); printf("total Deallocs = %9ld\n", ourMemStats.totalDeallocs);
printf("total Deallocs = %9lu\n", printf("total Bytes = %9ld\n", ourMemStats.totalBytes);
(unsigned long)ourMemStats.totalDeallocs); printf("peak Bytes = %9ld\n", ourMemStats.peakBytes);
printf("total Bytes = %9lu\n", printf("current Bytes = %9ld\n", ourMemStats.currentBytes);
(unsigned long)ourMemStats.totalBytes); #endif
printf("peak Bytes = %9lu\n",
(unsigned long)ourMemStats.peakBytes); #ifdef DO_MEM_LIST
printf("current Bytes = %9lu\n", if (ourMemList.count > 0) {
(unsigned long)ourMemStats.currentBytes); /* 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 #endif
} }