wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

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-2016 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 "wolfssl/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         WOLFSSL_LOCAL void* TrackMalloc(size_t sz);
00094         WOLFSSL_LOCAL void TrackFree(void* ptr);
00095         WOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz);
00096         WOLFSSL_LOCAL int InitMemoryTracker(void);
00097         WOLFSSL_LOCAL void ShowMemoryTracker(void);
00098     #else
00099         #define STATIC static
00100     #endif
00101 
00102 #ifdef WOLFSSL_DEBUG_MEMORY
00103     STATIC INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line)
00104 #else
00105     STATIC INLINE void* TrackMalloc(size_t sz)
00106 #endif
00107     {
00108         memoryTrack* mt;
00109 
00110         if (sz == 0)
00111             return NULL;
00112 
00113         mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
00114         if (mt == NULL)
00115             return NULL;
00116 
00117         mt->u.hint.thisSize   = sz;
00118         mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
00119 
00120 #ifdef WOLFSSL_DEBUG_MEMORY
00121         printf("Alloc: %p -> %u at %s:%d\n", mt->u.hint.thisMemory, (word32)sz, func, line);
00122 #endif
00123 
00124 #ifdef DO_MEM_STATS
00125         ourMemStats.totalAllocs++;
00126         ourMemStats.totalBytes   += sz;
00127         ourMemStats.currentBytes += sz;
00128         if (ourMemStats.currentBytes > ourMemStats.peakBytes)
00129             ourMemStats.peakBytes = ourMemStats.currentBytes;
00130 #endif
00131 
00132         return mt->u.hint.thisMemory;
00133     }
00134 
00135 
00136 #ifdef WOLFSSL_DEBUG_MEMORY
00137     STATIC INLINE void TrackFree(void* ptr, const char* func, unsigned int line)
00138 #else
00139     STATIC INLINE void TrackFree(void* ptr)
00140 #endif
00141     {
00142         memoryTrack* mt;
00143 
00144         if (ptr == NULL) {
00145             return;
00146         }
00147 
00148         mt = (memoryTrack*)ptr;
00149         --mt;   /* same as minus sizeof(memoryTrack), removes header */
00150 
00151 #ifdef DO_MEM_STATS
00152         ourMemStats.currentBytes -= mt->u.hint.thisSize;
00153         ourMemStats.totalDeallocs++;
00154 #endif
00155 
00156 #ifdef WOLFSSL_DEBUG_MEMORY
00157         printf("Free: %p -> %u at %s:%d\n", ptr, (word32)mt->u.hint.thisSize, func, line);
00158 #endif
00159 
00160         free(mt);
00161     }
00162 
00163 
00164 #ifdef WOLFSSL_DEBUG_MEMORY
00165     STATIC INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line)
00166 #else
00167     STATIC INLINE void* TrackRealloc(void* ptr, size_t sz)
00168 #endif
00169     {
00170     #ifdef WOLFSSL_DEBUG_MEMORY
00171         void* ret = TrackMalloc(sz, func, line);
00172     #else
00173         void* ret = TrackMalloc(sz);
00174     #endif
00175 
00176         if (ptr) {
00177             /* if realloc is bigger, don't overread old ptr */
00178             memoryTrack* mt = (memoryTrack*)ptr;
00179             --mt;  /* same as minus sizeof(memoryTrack), removes header */
00180 
00181             if (mt->u.hint.thisSize < sz)
00182                 sz = mt->u.hint.thisSize;
00183         }
00184 
00185         if (ret && ptr)
00186             XMEMCPY(ret, ptr, sz);
00187 
00188         if (ret) {
00189         #ifdef WOLFSSL_DEBUG_MEMORY
00190             TrackFree(ptr, func, line);
00191         #else
00192             TrackFree(ptr);
00193         #endif
00194         }
00195 
00196         return ret;
00197     }
00198 
00199 #ifdef WOLFSSL_TRACK_MEMORY
00200     STATIC INLINE int InitMemoryTracker(void)
00201     {
00202         int ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc);
00203         if (ret < 0) {
00204             printf("wolfSSL SetAllocators failed for track memory\n");
00205             return ret;
00206         }
00207 
00208     #ifdef DO_MEM_STATS
00209         ourMemStats.totalAllocs  = 0;
00210         ourMemStats.totalDeallocs = 0;
00211         ourMemStats.totalBytes   = 0;
00212         ourMemStats.peakBytes    = 0;
00213         ourMemStats.currentBytes = 0;
00214     #endif
00215 
00216         return ret;
00217     }
00218 
00219     STATIC INLINE void ShowMemoryTracker(void)
00220     {
00221     #ifdef DO_MEM_STATS
00222         printf("total   Allocs = %9lu\n",
00223                                        (unsigned long)ourMemStats.totalAllocs);
00224         printf("total   Deallocs = %9lu\n",
00225                                        (unsigned long)ourMemStats.totalDeallocs);
00226         printf("total   Bytes  = %9lu\n",
00227                                        (unsigned long)ourMemStats.totalBytes);
00228         printf("peak    Bytes  = %9lu\n",
00229                                        (unsigned long)ourMemStats.peakBytes);
00230         printf("current Bytes  = %9lu\n",
00231                                        (unsigned long)ourMemStats.currentBytes);
00232     #endif
00233     }
00234 #endif
00235 
00236 #endif /* USE_WOLFSSL_MEMORY */
00237 
00238 #endif /* WOLFSSL_MEM_TRACK_H */
00239 
00240