diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 76cd20f71..a30d49513 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -130,7 +130,7 @@ #include "wolfcrypt/benchmark/benchmark.h" #ifdef USE_WOLFSSL_MEMORY - #include "wolfssl/mem_track.h" + #include "wolfssl/wolfcrypt/mem_track.h" #endif void bench_des(void); diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 663da8d41..865022923 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -43,6 +43,7 @@ #include #endif + /* Set these to default values initially. */ static wolfSSL_Malloc_cb malloc_function = 0; static wolfSSL_Free_cb free_function = 0; @@ -72,15 +73,24 @@ int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf, return res; } - +#ifdef WOLFSSL_DEBUG_MEMORY +void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line) +#else void* wolfSSL_Malloc(size_t size) +#endif { void* res = 0; - if (malloc_function) + if (malloc_function) { + #ifdef WOLFSSL_DEBUG_MEMORY + res = malloc_function(size, func, line); + #else res = malloc_function(size); - else + #endif + } + else { res = malloc(size); + } #ifdef WOLFSSL_MALLOC_CHECK if (res == NULL) @@ -90,22 +100,42 @@ void* wolfSSL_Malloc(size_t size) return res; } +#ifdef WOLFSSL_DEBUG_MEMORY +void wolfSSL_Free(void *ptr, const char* func, unsigned int line) +#else void wolfSSL_Free(void *ptr) +#endif { - if (free_function) + if (free_function) { + #ifdef WOLFSSL_DEBUG_MEMORY + free_function(ptr, func, line); + #else free_function(ptr); - else + #endif + } + else { free(ptr); + } } +#ifdef WOLFSSL_DEBUG_MEMORY +void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line) +#else void* wolfSSL_Realloc(void *ptr, size_t size) +#endif { void* res = 0; - if (realloc_function) + if (realloc_function) { + #ifdef WOLFSSL_DEBUG_MEMORY + res = realloc_function(ptr, size, func, line); + #else res = realloc_function(ptr, size); - else + #endif + } + else { res = realloc(ptr, size); + } return res; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6b7ddb1ab..b776a47aa 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -143,7 +143,7 @@ #include "wolfcrypt/test/test.h" #ifdef USE_WOLFSSL_MEMORY - #include "wolfssl/mem_track.h" + #include "wolfssl/wolfcrypt/mem_track.h" #endif diff --git a/wolfssl/include.am b/wolfssl/include.am index bd5abbb6b..a02488fc8 100644 --- a/wolfssl/include.am +++ b/wolfssl/include.am @@ -18,8 +18,7 @@ nobase_include_HEADERS+= \ wolfssl/version.h \ wolfssl/options.h \ wolfssl/ocsp.h \ - wolfssl/crl.h \ - wolfssl/mem_track.h + wolfssl/crl.h noinst_HEADERS+= \ wolfssl/internal.h diff --git a/wolfssl/test.h b/wolfssl/test.h index d979872ca..f8dc9d18f 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #ifdef ATOMIC_USER #include diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 14f162a45..db5701f2a 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -54,7 +54,8 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/logging.h \ wolfssl/wolfcrypt/memory.h \ wolfssl/wolfcrypt/mpi_class.h \ - wolfssl/wolfcrypt/mpi_superclass.h + wolfssl/wolfcrypt/mpi_superclass.h \ + wolfssl/wolfcrypt/mem_track.h noinst_HEADERS+= \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ diff --git a/wolfssl/mem_track.h b/wolfssl/wolfcrypt/mem_track.h similarity index 71% rename from wolfssl/mem_track.h rename to wolfssl/wolfcrypt/mem_track.h index 3b9906505..4d69a565b 100644 --- a/wolfssl/mem_track.h +++ b/wolfssl/wolfcrypt/mem_track.h @@ -20,6 +20,40 @@ */ +/* The memory tracker overrides the wolfSSL memory callback system and uses a + * static to track the total, peak and currently allocated bytes. + * + * If you are already using the memory callbacks then enabling this will + * override the memory callbacks and prevent your memory callbacks from + * working. This assumes malloc() and free() are available. Feel free to + * customize this for your needs. + + * The enable this feature define the following: + * #define USE_WOLFSSL_MEMORY + * #define WOLFSSL_TRACK_MEMORY + * + * On startup call: + * InitMemoryTracker(); + * + * When ready to dump the memory report call: + * ShowMemoryTracker(); + * + * Report example: + * total Allocs = 228 + * total Bytes = 93442 + * peak Bytes = 8840 + * current Bytes = 0 + * + * + * You can also: + * #define WOLFSSL_DEBUG_MEMORY + * + * To print every alloc/free along with the function and line number. + * Example output: + * Alloc: 0x7fa14a500010 -> 120 at wc_InitRng:496 + * Free: 0x7fa14a500010 -> 120 at wc_FreeRng:606 + */ + #ifndef WOLFSSL_MEM_TRACK_H #define WOLFSSL_MEM_TRACK_H @@ -64,7 +98,11 @@ #define STATIC static #endif +#ifdef WOLFSSL_DEBUG_MEMORY + STATIC INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line) +#else STATIC INLINE void* TrackMalloc(size_t sz) +#endif { memoryTrack* mt; @@ -78,6 +116,10 @@ mt->u.hint.thisSize = sz; mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack); +#ifdef WOLFSSL_DEBUG_MEMORY + printf("Alloc: %p -> %u at %s:%d\n", mt->u.hint.thisMemory, (word32)sz, func, line); +#endif + #ifdef DO_MEM_STATS ourMemStats.totalAllocs++; ourMemStats.totalBytes += sz; @@ -90,7 +132,11 @@ } +#ifdef WOLFSSL_DEBUG_MEMORY + STATIC INLINE void TrackFree(void* ptr, const char* func, unsigned int line) +#else STATIC INLINE void TrackFree(void* ptr) +#endif { memoryTrack* mt; @@ -105,13 +151,25 @@ ourMemStats.currentBytes -= mt->u.hint.thisSize; #endif +#ifdef WOLFSSL_DEBUG_MEMORY + printf("Free: %p -> %u at %s:%d\n", ptr, (word32)mt->u.hint.thisSize, func, line); +#endif + free(mt); } +#ifdef WOLFSSL_DEBUG_MEMORY + STATIC INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line) +#else STATIC INLINE void* TrackRealloc(void* ptr, size_t sz) +#endif { + #ifdef WOLFSSL_DEBUG_MEMORY + void* ret = TrackMalloc(sz, func, line); + #else void* ret = TrackMalloc(sz); + #endif if (ptr) { /* if realloc is bigger, don't overread old ptr */ @@ -125,8 +183,13 @@ if (ret && ptr) memcpy(ret, ptr, sz); - if (ret) + if (ret) { + #ifdef WOLFSSL_DEBUG_MEMORY + TrackFree(ptr, func, line); + #else TrackFree(ptr); + #endif + } return ret; } diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 30d5c1626..5bf8c26f6 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -33,22 +33,31 @@ extern "C" { #endif -typedef void *(*wolfSSL_Malloc_cb)(size_t size); -typedef void (*wolfSSL_Free_cb)(void *ptr); -typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); +#ifdef WOLFSSL_DEBUG_MEMORY + typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line); + typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line); + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line); + WOLFSSL_API void wolfSSL_Free(void *ptr, const char* func, unsigned int line); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line); +#else + typedef void *(*wolfSSL_Malloc_cb)(size_t size); + typedef void (*wolfSSL_Free_cb)(void *ptr); + typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); + + /* Public in case user app wants to use XMALLOC/XFREE */ + WOLFSSL_API void* wolfSSL_Malloc(size_t size); + WOLFSSL_API void wolfSSL_Free(void *ptr); + WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); +#endif /* Public set function */ WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function, wolfSSL_Free_cb free_function, wolfSSL_Realloc_cb realloc_function); -/* Public in case user app wants to use XMALLOC/XFREE */ -WOLFSSL_API void* wolfSSL_Malloc(size_t size); -WOLFSSL_API void wolfSSL_Free(void *ptr); -WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); - - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 2c134d542..42d442f8a 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -189,9 +189,15 @@ && !defined(WOLFSSL_uITRON4) && !defined(WOLFSSL_uTKERNEL2) /* default C runtime, can install different routines at runtime via cbs */ #include - #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s))) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} - #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) + #ifdef WOLFSSL_DEBUG_MEMORY + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s), __func__, __LINE__)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp), __func__, __LINE__);} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), __func__, __LINE__) + #else + #define XMALLOC(s, h, t) ((void)h, (void)t, wolfSSL_Malloc((s))) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} + #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) + #endif #endif #ifndef STRING_USER