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 };
#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");
}

View File

@@ -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
}

View File

@@ -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 <pthread.h>
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
}