Xuyi Wang / wolfcrypt

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mem_track.h Source File

mem_track.h

00001 /* mem_track.h
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 /* The memory tracker overrides the wolfSSL memory callback system and uses a
00024  * static to track the total, peak and currently allocated bytes.
00025  *
00026  * If you are already using the memory callbacks then enabling this will
00027  * override the memory callbacks and prevent your memory callbacks from
00028  * working. This assumes malloc() and free() are available. Feel free to
00029  * customize this for your needs.
00030 
00031  * The enable this feature define the following:
00032  * #define USE_WOLFSSL_MEMORY
00033  * #define WOLFSSL_TRACK_MEMORY
00034  *
00035  * On startup call:
00036  * InitMemoryTracker();
00037  *
00038  * When ready to dump the memory report call:
00039  * ShowMemoryTracker();
00040  *
00041  * Report example:
00042  * total   Allocs =       228
00043  * total   Bytes  =     93442
00044  * peak    Bytes  =      8840
00045  * current Bytes  =         0
00046  *
00047  *
00048  * You can also:
00049  * #define WOLFSSL_DEBUG_MEMORY
00050  *
00051  * To print every alloc/free along with the function and line number.
00052  * Example output:
00053  * Alloc: 0x7fa14a500010 -> 120 at wc_InitRng:496
00054  * Free: 0x7fa14a500010 -> 120 at wc_FreeRng:606
00055  */
00056 
00057 
00058 #ifndef WOLFSSL_MEM_TRACK_H
00059 #define WOLFSSL_MEM_TRACK_H
00060 
00061 #if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
00062 
00063     #include "wolfcrypt/logging.h"
00064 
00065     typedef struct memoryStats {
00066         size_t totalAllocs;     /* number of allocations */
00067         size_t totalDeallocs;   /* number of deallocations */
00068         size_t totalBytes;      /* total number of bytes allocated */
00069         size_t peakBytes;       /* concurrent max bytes */
00070         size_t currentBytes;    /* total current bytes in use */
00071     } memoryStats;
00072 
00073     typedef struct memHint {
00074         size_t thisSize;      /* size of this memory */
00075         void*  thisMemory;    /* actual memory for user */
00076     } memHint;
00077 
00078     typedef struct memoryTrack {
00079         union {
00080             memHint hint;
00081             byte    alignit[16];   /* make sure we have strong alignment */
00082         } u;
00083     } memoryTrack;
00084 
00085     #if defined(WOLFSSL_TRACK_MEMORY)
00086         #define DO_MEM_STATS
00087         static memoryStats ourMemStats;
00088     #endif
00089 
00090     /* if defined to not using inline then declare function prototypes */
00091     #ifdef NO_INLINE
00092         #define STATIC
00093         #ifdef WOLFSSL_DEBUG_MEMORY
00094             WOLFSSL_LOCAL void* TrackMalloc(size_t sz, const char* func, unsigned int line);
00095             WOLFSSL_LOCAL void TrackFree(void* ptr, const char* func, unsigned int line);
00096             WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line);
00097         #else
00098             WOLFSSL_LOCAL void* TrackMalloc(size_t sz);
00099             WOLFSSL_LOCAL void TrackFree(void* ptr);
00100             WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz);
00101         #endif
00102         WOLFSSL_LOCAL int InitMemoryTracker(void);
00103         WOLFSSL_LOCAL void ShowMemoryTracker(void);
00104     #else
00105         #define STATIC static
00106     #endif
00107 
00108 #ifdef WOLFSSL_DEBUG_MEMORY
00109     STATIC WC_INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line)
00110 #else
00111     STATIC WC_INLINE void* TrackMalloc(size_t sz)
00112 #endif
00113     {
00114         memoryTrack* mt;
00115 
00116         if (sz == 0)
00117             return NULL;
00118 
00119         mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
00120         if (mt == NULL)
00121             return NULL;
00122 
00123         mt->u.hint.thisSize   = sz;
00124         mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
00125 
00126 #ifdef WOLFSSL_DEBUG_MEMORY
00127         printf("Alloc: %p -> %u at %s:%d\n", mt->u.hint.thisMemory, (word32)sz, func, line);
00128 #endif
00129 
00130 #ifdef DO_MEM_STATS
00131         ourMemStats.totalAllocs++;
00132         ourMemStats.totalBytes   += sz;
00133         ourMemStats.currentBytes += sz;
00134         if (ourMemStats.currentBytes > ourMemStats.peakBytes)
00135             ourMemStats.peakBytes = ourMemStats.currentBytes;
00136 #endif
00137 
00138         return mt->u.hint.thisMemory;
00139     }
00140 
00141 
00142 #ifdef WOLFSSL_DEBUG_MEMORY
00143     STATIC WC_INLINE void TrackFree(void* ptr, const char* func, unsigned int line)
00144 #else
00145     STATIC WC_INLINE void TrackFree(void* ptr)
00146 #endif
00147     {
00148         memoryTrack* mt;
00149 
00150         if (ptr == NULL) {
00151             return;
00152         }
00153 
00154         mt = (memoryTrack*)ptr;
00155         --mt;   /* same as minus sizeof(memoryTrack), removes header */
00156 
00157 #ifdef DO_MEM_STATS
00158         ourMemStats.currentBytes -= mt->u.hint.thisSize;
00159         ourMemStats.totalDeallocs++;
00160 #endif
00161 
00162 #ifdef WOLFSSL_DEBUG_MEMORY
00163         printf("Free: %p -> %u at %s:%d\n", ptr, (word32)mt->u.hint.thisSize, func, line);
00164 #endif
00165 
00166         free(mt);
00167     }
00168 
00169 
00170 #ifdef WOLFSSL_DEBUG_MEMORY
00171     STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line)
00172 #else
00173     STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz)
00174 #endif
00175     {
00176     #ifdef WOLFSSL_DEBUG_MEMORY
00177         void* ret = TrackMalloc(sz, func, line);
00178     #else
00179         void* ret = TrackMalloc(sz);
00180     #endif
00181 
00182         if (ptr) {
00183             /* if realloc is bigger, don't overread old ptr */
00184             memoryTrack* mt = (memoryTrack*)ptr;
00185             --mt;  /* same as minus sizeof(memoryTrack), removes header */
00186 
00187             if (mt->u.hint.thisSize < sz)
00188                 sz = mt->u.hint.thisSize;
00189         }
00190 
00191         if (ret && ptr)
00192             XMEMCPY(ret, ptr, sz);
00193 
00194         if (ret) {
00195         #ifdef WOLFSSL_DEBUG_MEMORY
00196             TrackFree(ptr, func, line);
00197         #else
00198             TrackFree(ptr);
00199         #endif
00200         }
00201 
00202         return ret;
00203     }
00204 
00205 #ifdef WOLFSSL_TRACK_MEMORY
00206     STATIC WC_INLINE int InitMemoryTracker(void)
00207     {
00208         int ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc);
00209         if (ret < 0) {
00210             printf("wolfSSL SetAllocators failed for track memory\n");
00211             return ret;
00212         }
00213 
00214     #ifdef DO_MEM_STATS
00215         ourMemStats.totalAllocs  = 0;
00216         ourMemStats.totalDeallocs = 0;
00217         ourMemStats.totalBytes   = 0;
00218         ourMemStats.peakBytes    = 0;
00219         ourMemStats.currentBytes = 0;
00220     #endif
00221 
00222         return ret;
00223     }
00224 
00225     STATIC WC_INLINE void ShowMemoryTracker(void)
00226     {
00227     #ifdef DO_MEM_STATS
00228         printf("total   Allocs   = %9lu\n",
00229                                        (unsigned long)ourMemStats.totalAllocs);
00230         printf("total   Deallocs = %9lu\n",
00231                                        (unsigned long)ourMemStats.totalDeallocs);
00232         printf("total   Bytes    = %9lu\n",
00233                                        (unsigned long)ourMemStats.totalBytes);
00234         printf("peak    Bytes    = %9lu\n",
00235                                        (unsigned long)ourMemStats.peakBytes);
00236         printf("current Bytes    = %9lu\n",
00237                                        (unsigned long)ourMemStats.currentBytes);
00238     #endif
00239     }
00240 
00241     STATIC WC_INLINE int CleanupMemoryTracker(void)
00242     {
00243         /* restore default allocators */
00244         return wolfSSL_ResetAllocators();
00245     }
00246 #endif
00247 
00248 #endif /* USE_WOLFSSL_MEMORY */
00249 
00250 #endif /* WOLFSSL_MEM_TRACK_H */
00251 
00252