mkernel 0.0.2
Micro-kernel framework, everything as a module
memdbg.c
Go to the documentation of this file.
1
19#include "memdbg.h"
20#include <string.h> /* memset, memcpy, memmove */
21#include <stdio.h> /* asprintf */
22#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
23
24/* Documented in header file */
26 const size_t Size,
27 const char* File,
28 const int Line,
29 const char* CompilDate,
30 const char* CompilTime,
31 const char* Function
32)
33{
34 /* Memory allocation */
35 void* l_tmp = malloc(Size);
36 if (NULL == l_tmp) return (l_tmp);
37
38 /* If successful, track the memory block */
39#pragma GCC diagnostic push /* save the actual diag context */
40#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" /* locally disable maybe warnings */
41 if (0!=memtrack_addblock( l_tmp, Size, File,Line,CompilDate,CompilTime,Function)) {
42#pragma GCC diagnostic pop /* restore previous diag context */
43 /* If tracking fails, the whole allocation fails */
44 free(l_tmp);
45 l_tmp = NULL;
46 };
47
48 return l_tmp;
49}
50
51/* Documented in header file */
53 void* Ptr,
54 const char* File,
55 const int Line,
56 const char* CompilDate,
57 const char* CompilTime,
58 const char* Function
59)
60{
61 /* If the pointer was not NULL, it was tracked, remove it from the tracked
62 * list. If it was not tracked, removing returns an error. Abort the
63 * process as it should never have an untracked pointer. Either it was
64 * allocated from a non instrumented binary, or it was allocated from
65 * a non monitored function (see memory.h) or there is a bug in the
66 * memory leak tracker. */
67 if (NULL!=Ptr)
68 if (0!=memtrack_delblock(Ptr,File,Line,CompilDate,CompilTime,Function))
69 abort();
70
71 /* If the pointer was NULL or tracked, forward it to the real free */
72 free(Ptr);
73}
74
75/* Documented in header file */
77 const size_t NMemb,
78 const size_t Size,
79 const char* File,
80 const int Line,
81 const char* CompilDate,
82 const char* CompilTime,
83 const char* Function
84)
85{
86 void* l_tmp;
87
88 /* Use the dbg_malloc function to allocate the memory */
89 l_tmp = dbg_malloc(
90 NMemb*Size,
91 File,Line,CompilDate,CompilTime,Function);
92
93 /* Implement the calloc specific behavior compared to simple malloc:
94 * it fills the allocated memory block with 0 */
95 if (NULL != l_tmp)
96 memset((char*)l_tmp, 0, NMemb*Size);
97
98 return l_tmp;
99}
100
101/* Documented in header file */
103 void* Ptr,
104 const size_t Size,
105 const char* File,
106 const int Line,
107 const char* CompilDate,
108 const char* CompilTime,
109 const char* Function
110)
111{
112 size_t l_oldsize;
113 char *newblk;
115 /* NULL is not tracked but valid */
116 if (NULL==Ptr) {
117 l_oldsize=0;
118 } else {
119 /* Fetch existing block size */
120 l_oldsize = memtrack_getblocksize(Ptr);
121
122 /* This is probably a bug in the memory tracker.
123 * It should not track zero sized blocks */
124 if (0==l_oldsize)
125 abort();
126 }
127
128 /* If new size is 0, then act as free, like realloc */
129 if (0==Size) {
130 dbg_free(Ptr,
131 File,Line,CompilDate,CompilTime,Function
132 );
133 return Ptr;
134 }
135
136 /* New sized block allocation to simulate the worst case scenario and
137 * test a pointer change, a data loss (in case of shrink) */
138 newblk=(char*)dbg_malloc(
139 Size,
140 File,Line,CompilDate,CompilTime,Function
141 );
142 /* The new block can fail */
143 /* The real realloc function could succeed here, in case of inplace
144 * shrink in an OOM situation. */
145 if (NULL == newblk) return (newblk);
146
147 /* Copy only the relevant data from old block to new block, loosing extra
148 * data in case of shrink, and not initializing new data in case of
149 * increase */
150 memcpy(newblk,(char*)Ptr,(l_oldsize<Size?l_oldsize:Size));
151
152 /* Free old block */
153 dbg_free(
154 Ptr,
155 File,Line,CompilDate,CompilTime,Function
156 );
157
158 return (void*) newblk;
159}
160
161
162/* Documented in header file */
164 const char* Ptr,
165 const char* File,
166 const int Line,
167 const char* CompilDate,
168 const char* CompilTime,
169 const char* Function
170)
171{
172 char* l_newblk;
174 /* Use strdup to actually copy the string with its own return values and
175 * abort (SIGSEGV in case of NULL) */
176 l_newblk=NULL;
177 l_newblk=strdup(Ptr);
178
179 /* If the copy succeeded, try to track the memory allocation */
180 if (NULL != l_newblk)
181 if (0!=memtrack_addblock(
182 l_newblk,
183 strlen(l_newblk)+1,
184 File,Line,CompilDate,CompilTime,Function
185 )) {
186 /* If tracking fails, the whole operation is reverted and fails */
187 free(l_newblk);
188 l_newblk=NULL;
189 };
190
191 return l_newblk;
192}
193
194
195/* Documented in header file */
196int dbg_asprintf(char **p_Ptr,
197 const char* p_Format,
198 const char *File,
199 const int Line,
200 const char *CompilDate,
201 const char *CompilTime, const char *Function,
202 ...)
203{
204 int l_returncode;
205
206 /* NULL is not allowed, where would we store the result, then ? */
207 if(NULL==p_Ptr)
208 abort();
209
210 /* Limit the scope of the variadic manipulation variables */
211 {
212 va_list l_ap;
213 va_start (l_ap, Function);
214 /* Use the original vasprintf to build the formatted string */
217 l_returncode = vasprintf(p_Ptr, p_Format, l_ap);
218 va_end(l_ap);
219 }
220
221 /* If formatting succeeded, try to track the memory allocation */
222 if (-1 != l_returncode)
223 if (1==memtrack_addblock(
224 *p_Ptr,
225 strlen (*p_Ptr)+1,
226 File,Line,CompilDate,CompilTime,Function
227 )) {
228 /* If tracking fails, the whole operation is reverted and fails */
229 free(*p_Ptr);
230 l_returncode=-2;
231 };
232
233 return l_returncode;
234}
235
void * dbg_malloc(const size_t Size, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function)
Malloc compatible standard allocation.
Definition: memdbg.c:25
void * dbg_calloc(const size_t NMemb, const size_t Size, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function)
Allocate a table of item from the size of each and number.
Definition: memdbg.c:76
void * dbg_realloc(void *Ptr, const size_t Size, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function)
Resize an already allocated and tracked block.
Definition: memdbg.c:102
int dbg_asprintf(char **p_Ptr, const char *p_Format, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function,...)
Build a formatted string with allocation.
Definition: memdbg.c:196
void dbg_free(void *Ptr, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function)
Free compatible standard memory release.
Definition: memdbg.c:52
char * dbg_strdup(const char *Ptr, const char *File, const int Line, const char *CompilDate, const char *CompilTime, const char *Function)
String duplication with allocation.
Definition: memdbg.c:163
Memory leak tracker header.
#define malloc(size)
Same syntaxt and same behavior than regular malloc function, with memory leaks tracking.
Definition: memory.h:32
#define strdup(chaine)
Same syntaxt and same behavior than regular strdup function, with memory leaks tracking.
Definition: memory.h:44
#define free(ptr)
Same syntaxt and same behavior than regular free function, with memory leaks tracking.
Definition: memory.h:41
size_t(* memtrack_getblocksize)(const void *p_Ptr)
Functor to get size of a specific memory block.
Definition: memtrack.c:621
unsigned int(* memtrack_delblock)(const void *p_Ptr, const char *p_File, const int p_Line, const char *p_CompilDate, const char *p_CompilTime, const char *p_Function)
Functor to unregister an allocated memory block metadata.
Definition: memtrack.c:603
unsigned int(* memtrack_addblock)(const void *p_Ptr, const size_t p_Size, const char *p_File, const int p_Line, const char *p_CompilDate, const char *p_CompilTime, const char *p_Function)
Functor to register an allocated memory block metadata.
Definition: memtrack.c:593
#define NULL
Definition: mkernel-opt.c:64