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