Line data Source code
1 : /** @file memtrack.c
2 : * @brief Memory block metadata tracking implementation
3 : * @date 25/09/2006
4 : * @author François Cerbelle (Fanfan), francois@cerbelle.net
5 : * @copyright Copyright (c) 1997-2024, François Cerbelle
6 : *
7 : * Originally inspired by "L'art du code", Steve Maguire, Microsoft Press
8 : *
9 : * @internal
10 : * Compiler gcc
11 : * Last modified 2024-08-21 13:20
12 : * Organization Cerbelle.net
13 : * Company Home
14 : *
15 : * This source code is released for free distribution under the terms of the
16 : * GNU General Public License as published by the Free Software Foundation.
17 : */
18 :
19 : #include "memtrack.h"
20 : #include <string.h> /* strdup */
21 : #include <stdio.h> /* fprintf */
22 :
23 : static struct MemBlock *Head; /**< Memory blocks metadata list start sentinal */
24 : static struct MemBlock *Tail; /**< Memory blocks metadata list end sentinal */
25 : static uint64_t NbBlocks; /**< Memory blocks metadata counter */
26 : static uint64_t RAMSize; /**< Memory blocks metadata RAM sum */
27 :
28 : /* Early definition, documented in the implementation below */
29 : static unsigned int memtrack_init();
30 :
31 : /* Early definition, documented in the implementation below */
32 : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
33 : const size_t p_Size,
34 : const char *p_File,
35 : const int p_Line,
36 : const char *p_CompilDate,
37 : const char *p_CompilTime,
38 : const char *p_Function);
39 :
40 : /* Early definition, documented in the implementation below */
41 : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
42 : const char *p_File,
43 : const int p_Line,
44 : const char *p_CompilDate,
45 : const char *p_CompilTime,
46 : const char *p_Function);
47 :
48 : /* Early definition, documented in the implementation below */
49 : static uint64_t memtrack_dumpblocks_preinit();
50 :
51 : /* Early definition, documented in the implementation below */
52 : static uint64_t memtrack_getallocatedblocks_preinit();
53 :
54 : /* Early definition, documented in the implementation below */
55 : static uint64_t memtrack_getallocatedRAM_preinit();
56 :
57 : /* Early definition, documented in the implementation below */
58 : static size_t memtrack_getblocksize_preinit(const void *p_Ptr);
59 :
60 : /* Early definition, documented in the implementation below */
61 : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
62 : const size_t p_Size,
63 : const char *p_File,
64 : const int p_Line,
65 : const char *p_CompilDate,
66 : const char *p_CompilTime,
67 : const char *p_Function);
68 :
69 : /* Early definition, documented in the implementation below */
70 : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
71 : const char *p_File,
72 : const int p_Line,
73 : const char *p_CompilDate,
74 : const char *p_CompilTime,
75 : const char *p_Function);
76 :
77 : /* Early definition, documented in the implementation below */
78 : static uint64_t memtrack_dumpblocks_postinit();
79 :
80 : /* Early definition, documented in the implementation below */
81 : static uint64_t memtrack_getallocatedblocks_postinit();
82 :
83 : /* Early definition, documented in the implementation below */
84 : static uint64_t memtrack_getallocatedRAM_postinit();
85 :
86 : /* Early definition, documented in the implementation below */
87 : static size_t memtrack_getblocksize_postinit(const void *p_Ptr);
88 :
89 : /*******************/
90 : /* Implementations */
91 : /*******************/
92 :
93 : /** Memory block metadata list reset
94 : *
95 : * This function is not defined in the header file because it should never be
96 : * used. It is exported because it is used by the unit tests. NEVER USE IT, it
97 : * will crash your code.
98 : */
99 2364 : void memtrack_reset()
100 : {
101 : /* Ne réinitialise que si nécessaire */
102 2364 : if ( memtrack_addblock == memtrack_addblock_preinit)
103 1182 : return;
104 :
105 : /* Déconfiguration des foncteurs */
106 1182 : memtrack_addblock = memtrack_addblock_preinit;
107 1182 : memtrack_delblock = memtrack_delblock_preinit;
108 1182 : memtrack_dumpblocks = memtrack_dumpblocks_preinit;
109 1182 : memtrack_getallocatedblocks = memtrack_getallocatedblocks_preinit;
110 1182 : memtrack_getallocatedRAM = memtrack_getallocatedRAM_preinit;
111 1182 : memtrack_getblocksize = memtrack_getblocksize_preinit;
112 :
113 : /* Purge de la liste */
114 2892 : while (Tail!=Head->Next) {
115 1710 : memtrack_delblock_postinit(Head->Next->Ptr,NULL,0,NULL,NULL,NULL);
116 : }
117 :
118 : /* Réinitialization des pointeurs */
119 1182 : free(Head);
120 1182 : free(Tail);
121 1182 : Head=NULL;
122 1182 : Tail=NULL;
123 : }
124 :
125 : /** Memory blocks metadata list initialization
126 : *
127 : * This function is private, not meant to be called externally, it is
128 : * automatically called by other functions at the very first usage. It
129 : * initializes the memory block metadata list, with start and end sentinels. It
130 : * needs to be executed before the real list manipulation functions.
131 : *
132 : * Each real manipulation function has two private static implementations,
133 : * uninitialized and initialized, and a publicly exported functor which is
134 : * referencing the uninitialized form by default. The uninitialized forms first
135 : * call this initialization function which makes the functos reference the
136 : * initialized forms.
137 : *
138 : * \return Initialization status
139 : * \retval 0 in case of success
140 : */
141 7327 : static unsigned int memtrack_init()
142 : {
143 7327 : Head = (TMemBlock *) malloc(sizeof(TMemBlock));
144 7327 : Tail = (TMemBlock *) malloc(sizeof(TMemBlock));
145 :
146 7327 : if ((NULL==Head)||(NULL==Tail)) {
147 880 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
148 : __FILE__,__LINE__);
149 880 : return 1;
150 : }
151 6447 : Head->Prev = (TMemBlock *) NULL;
152 6447 : Head->Next = Tail;
153 6447 : Tail->Next = (TMemBlock *) NULL;
154 6447 : Tail->Prev = Head;
155 6447 : Tail->Ptr = Head->Ptr = (void *)NULL;
156 6447 : Tail->Size = Head->Size = 0;
157 6447 : Tail->File = Head->File = (char *)NULL;
158 6447 : Tail->Line = Head->Line = 0;
159 6447 : Tail->CompilDate = Head->CompilDate = (char *)NULL;
160 6447 : Tail->CompilTime = Head->CompilTime = (char *)NULL;
161 6447 : Tail->Function = Head->Function = (char *)NULL;
162 :
163 : /* Initialisation des compteurs */
164 6447 : NbBlocks=0;
165 6447 : RAMSize=0;
166 :
167 : /* Modification des foncteurs pour utiliser les fonctions définitives */
168 6447 : memtrack_addblock = memtrack_addblock_postinit;
169 6447 : memtrack_delblock = memtrack_delblock_postinit;
170 6447 : memtrack_dumpblocks = memtrack_dumpblocks_postinit;
171 6447 : memtrack_getallocatedblocks = memtrack_getallocatedblocks_postinit;
172 6447 : memtrack_getallocatedRAM = memtrack_getallocatedRAM_postinit;
173 6447 : memtrack_getblocksize = memtrack_getblocksize_postinit;
174 :
175 6447 : return 0;
176 : }
177 :
178 :
179 : /** Add a memory block metadata entry to the list (preinit)
180 : *
181 : * Default function for the memtrack_addblock functor until initialized by the
182 : * memtrack_init function. It is executed if the functor is called before
183 : * initialization. It triggers initialization with functors definitive
184 : * assignation to the *_postinit functions and calls the actual postinit
185 : * function.
186 : *
187 : * \sa memtrack_addblock
188 : * \sa memtrack_addblock_postinit
189 : */
190 3525 : static unsigned int memtrack_addblock_preinit(const void *p_Ptr,
191 : const size_t p_Size,
192 : const char *p_File,
193 : const int p_Line,
194 : const char *p_CompilDate,
195 : const char *p_CompilTime,
196 : const char *p_Function)
197 : {
198 : /* Initialisation de la liste */
199 3525 : if (0!=memtrack_init()) {
200 780 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
201 : __FILE__,__LINE__);
202 : /* OOM */
203 780 : return 1;
204 : }
205 :
206 : /* Appel de la fonction réelle */
207 2745 : return memtrack_addblock(p_Ptr, p_Size, p_File, p_Line, p_CompilDate,
208 : p_CompilTime, p_Function);
209 : }
210 :
211 : /** Remove a memory block metadata entry from the list (preinit)
212 : *
213 : * Default function for the memtrack_delblock functor until initialized by the
214 : * memtrack_init function. It is executed if the functor is called before
215 : * initialization. It triggers initialization with functors definitive
216 : * assignation to the *_postinit functions and calls the actual postinit
217 : * function.
218 : *
219 : * \sa memtrack_delblock
220 : * \sa memtrack_delblock_postinit
221 : */
222 24 : static unsigned int memtrack_delblock_preinit(const void *p_Ptr,
223 : const char *p_File,
224 : const int p_Line,
225 : const char *p_CompilDate,
226 : const char *p_CompilTime,
227 : const char *p_Function)
228 : {
229 : /* Initialisation de la liste */
230 24 : if (0!=memtrack_init()) {
231 20 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
232 : __FILE__,__LINE__);
233 : /* OOM */
234 20 : return 1;
235 : }
236 :
237 : /* Appel de la fonction réelle */
238 4 : return memtrack_delblock(p_Ptr, p_File, p_Line, p_CompilDate,
239 : p_CompilTime, p_Function);
240 : }
241 :
242 : /** Dump memory block metadata entries from the list (preinit)
243 : *
244 : * Default function for the memtrack_dumpblocks functor until initialized by the
245 : * memtrack_init function. It is executed if the functor is called before
246 : * initialization. It triggers initialization with functors definitive
247 : * assignation to the *_postinit functions and calls the actual postinit
248 : * function.
249 : *
250 : * \sa memtrack_dumpblocks
251 : * \sa memtrack_dumpblocks_postinit
252 : */
253 39 : static uint64_t memtrack_dumpblocks_preinit()
254 : {
255 : /* Initialisation de la liste */
256 39 : if (0!=memtrack_init()) {
257 20 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
258 : __FILE__,__LINE__);
259 : /* OOM */
260 20 : return 0;
261 : }
262 :
263 : /* Appel de la fonction réelle */
264 19 : return memtrack_dumpblocks();
265 : }
266 :
267 : /** Get the memory block metadata entries count (preinit)
268 : *
269 : * Default function for the memtrack_getallocatedblocks functor until
270 : * initialized by the memtrack_init function. It is executed if the functor is
271 : * called before initialization. It triggers initialization with functors
272 : * definitive assignation to the *_postinit functions and calls the actual
273 : * postinit function.
274 : *
275 : * \sa memtrack_getallocatedblocks
276 : * \sa memtrack_getallocatedblocks_postinit
277 : */
278 3648 : static uint64_t memtrack_getallocatedblocks_preinit()
279 : {
280 : /* Initialisation de la liste */
281 3648 : if (0!=memtrack_init()) {
282 20 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
283 : __FILE__,__LINE__);
284 : /* OOM */
285 20 : return 0;
286 : }
287 :
288 : /* Appel de la fonction réelle */
289 3628 : return memtrack_getallocatedblocks();
290 : }
291 :
292 : /** Get the memory block metadata entries total RAM (preinit)
293 : *
294 : * Default function for the memtrack_getallocatedRAM functor until
295 : * initialized by the memtrack_init function. It is executed if the functor is
296 : * called before initialization. It triggers initialization with functors
297 : * definitive assignation to the *_postinit functions and calls the actual
298 : * postinit function.
299 : *
300 : * \sa memtrack_getallocatedRAM
301 : * \sa memtrack_getallocatedRAM_postinit
302 : */
303 23 : static uint64_t memtrack_getallocatedRAM_preinit()
304 : {
305 : /* Initialisation de la liste */
306 23 : if (0!=memtrack_init()) {
307 20 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
308 : __FILE__,__LINE__);
309 : /* OOM */
310 20 : return 0;
311 : }
312 :
313 : /* Appel de la fonction réelle */
314 3 : return memtrack_getallocatedRAM();
315 : }
316 :
317 : /** Get a memory block RAM size (preinit)
318 : *
319 : * Default function for the memtrack_getblocksize functor until initialized by
320 : * the memtrack_init function. It is executed if the functor is called before
321 : * initialization. It triggers initialization with functors definitive
322 : * assignation to the *_postinit functions and calls the actual postinit
323 : * function.
324 : *
325 : * \sa memtrack_getblocksize
326 : * \sa memtrack_getblocksize_postinit
327 : */
328 68 : static size_t memtrack_getblocksize_preinit(const void *p_Ptr)
329 : {
330 : /* Initialisation de la liste */
331 68 : if (0!=memtrack_init()) {
332 20 : fprintf(stderr,"%s:%d Not enough memory to initialize memtracker\n",
333 : __FILE__,__LINE__);
334 : /* OOM */
335 20 : return 0;
336 : }
337 :
338 : /* Appel de la fonction réelle */
339 48 : return memtrack_getblocksize(p_Ptr);
340 : }
341 :
342 : /** Add a memory block metadata entry to the list (postinit)
343 : *
344 : * This function is referenced by the memtrack_addblock functor after
345 : * initialization. This is the real implementation of the feature.
346 : *
347 : * \sa memtrack_addblock
348 : * \sa memtrack_addblock_preinit
349 : */
350 13752 : static unsigned int memtrack_addblock_postinit(const void *p_Ptr,
351 : const size_t p_Size,
352 : const char *p_File,
353 : const int p_Line,
354 : const char *p_CompilDate,
355 : const char *p_CompilTime,
356 : const char *p_Function)
357 : {
358 : TMemBlock *l_tmp;
359 :
360 : /* Test de validité des données à enregistrer */
361 : /* Meme si malloc permet Size=0, ce n'est pas portable */
362 13752 : if ((NULL==p_Ptr)||
363 13096 : (0==p_Size)||
364 13066 : (NULL==p_File)||
365 13066 : (0==p_File[0])||
366 12508 : (0==p_Line)||
367 12478 : (NULL==p_CompilDate)||
368 12478 : (0==p_CompilDate[0])||
369 12172 : (NULL==p_CompilTime)||
370 12172 : (0==p_CompilTime[0])||
371 11866 : (NULL==p_Function)||
372 11866 : (0==p_Function[0])) {
373 2162 : fprintf(stderr,"%s:%d Null or empty parameters\n",__FILE__, __LINE__);
374 2162 : return 1;
375 : }
376 :
377 : /* On ne peut pas dupliquer un pointeur. Pour le modifier, il faut le
378 : * supprimer et le recréer, ce n'est pas le rôle de ces fonctions de
379 : * bas-niveau */
380 :
381 : /* Recherche du pointeur */
382 11590 : l_tmp = Head->Next;
383 28139 : while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
384 16549 : l_tmp = l_tmp->Next;
385 :
386 : /* Le bloc ne doit pas avoir été trouvé */
387 11590 : if (l_tmp != Tail) {
388 66 : fprintf(stderr,"%s:%d Memory bloc already registered\n",__FILE__, __LINE__);
389 66 : return 1;
390 : }
391 :
392 : /* Allocation d'un nouveau descripteur de bloc */
393 11524 : l_tmp = (TMemBlock *) malloc(sizeof(TMemBlock));
394 :
395 : /* Allocation réussie ? */
396 11524 : if (NULL == l_tmp) {
397 1892 : return 1;
398 : }
399 :
400 : /* Remplissage du descripteur */
401 9632 : l_tmp->Ptr = (void *)p_Ptr;
402 9632 : l_tmp->Size = p_Size;
403 9632 : if (NULL==(l_tmp->File = strdup(p_File?p_File:""))) {
404 76 : free(l_tmp);
405 76 : return 1;
406 : };
407 9556 : l_tmp->Line = p_Line;
408 9556 : if (NULL==(l_tmp->CompilDate = strdup(p_CompilDate?p_CompilDate:""))) {
409 0 : free(l_tmp->File);
410 0 : free(l_tmp);
411 0 : return 1;
412 : };
413 9556 : if (NULL==(l_tmp->CompilTime = strdup(p_CompilTime?p_CompilTime:""))) {
414 15 : free(l_tmp->CompilDate);
415 15 : free(l_tmp->File);
416 15 : free(l_tmp);
417 15 : return 1;
418 : };
419 9541 : if (NULL==(l_tmp->Function = strdup(p_Function?p_Function:""))) {
420 39 : free(l_tmp->CompilTime);
421 39 : free(l_tmp->CompilDate);
422 39 : free(l_tmp->File);
423 39 : free(l_tmp);
424 39 : return 1;
425 : };
426 :
427 : /* Ajout de la description dans la liste (Section critique) */
428 9502 : l_tmp->Prev = Tail->Prev;
429 9502 : l_tmp->Next = Tail;
430 9502 : l_tmp->Prev->Next = l_tmp->Next->Prev = l_tmp;
431 :
432 : /* Mise à jour des compteurs */
433 9502 : NbBlocks++;
434 9502 : RAMSize += p_Size;
435 :
436 9502 : return 0;
437 : }
438 :
439 : /** Remove a memory block metadata entry from the list (postinit)
440 : *
441 : * This function is referenced by the memtrack_addblock functor after
442 : * initialization. This is the real implementation of the feature.
443 : *
444 : * \sa memtrack_delblock
445 : * \sa memtrack_delblock_preinit
446 : */
447 7527 : static unsigned int memtrack_delblock_postinit(const void *p_Ptr,
448 : const char *p_File,
449 : const int p_Line,
450 : const char *p_CompilDate,
451 : const char *p_CompilTime,
452 : const char *p_Function)
453 : {
454 : TMemBlock *l_tmp;
455 : (void) p_File;
456 : (void) p_Line;
457 : (void) p_CompilDate;
458 : (void) p_CompilTime;
459 : (void) p_Function;
460 :
461 : /* Recherche de la description */
462 7527 : l_tmp = Head->Next;
463 10706 : while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
464 3179 : l_tmp = l_tmp->Next;
465 :
466 : /* Le bloc doit avoir été trouvé */
467 7527 : if (l_tmp == Tail) {
468 726 : fprintf(stderr,"%s:%d Block not found for deletion\n",__FILE__, __LINE__);
469 726 : return 1;
470 : }
471 :
472 : /* Libération des ressources acquises */
473 : /* On ne libère pas le bloc mémoire lui-même */
474 6801 : free(l_tmp->File);
475 6801 : free(l_tmp->CompilDate);
476 6801 : free(l_tmp->CompilTime);
477 6801 : free(l_tmp->Function);
478 :
479 : /* Retrait de la description de la liste (Section critique) */
480 6801 : l_tmp->Next->Prev = l_tmp->Prev;
481 6801 : l_tmp->Prev->Next = l_tmp->Next;
482 :
483 : /* Mise à jour des compteurs */
484 6801 : NbBlocks--;
485 6801 : RAMSize -= l_tmp->Size;
486 :
487 : /* Libération de la description */
488 6801 : free(l_tmp);
489 :
490 6801 : return 0;
491 : }
492 :
493 : /** Dump memory block metadata entries from the list (postinit)
494 : *
495 : * This function is referenced by the memtrack_addblock functor after
496 : * initialization. This is the real implementation of the feature.
497 : *
498 : * \sa memtrack_dumpblocks
499 : * \sa memtrack_dumpblocks_preinit
500 : */
501 7900 : static uint64_t memtrack_dumpblocks_postinit()
502 : {
503 : TMemBlock *l_tmp;
504 7900 : uint64_t l_NbBlocks = 0;;
505 :
506 7900 : if (Head->Next != Tail) {
507 : size_t l_BlockSize;
508 3454 : fprintf(stderr,
509 : "+----------------------------------------------------------------------------------------------------------+\n");
510 3454 : fprintf(stderr, "| %-104s |\n", "Memory Tracker Report");
511 3454 : fprintf(stderr,
512 : "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
513 3454 : fprintf(stderr,
514 : "| %-20s | %-20s | %-4s | %-15s | %-8s | %-22s |\n",
515 : "Function", "File", "Line", "Address", "Bytes",
516 : "Compiled");
517 3454 : fprintf(stderr,
518 : "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
519 :
520 3454 : l_tmp = Head->Next; /**< Curseur */
521 3454 : l_BlockSize = 0;
522 12188 : while (l_tmp != Tail) {
523 8734 : fprintf(stderr,
524 : "| %-20s | %-20s | %4d | %15p | %8lu | %11s @ %8s |\n",
525 : l_tmp->Function, l_tmp->File, l_tmp->Line,
526 8734 : l_tmp->Ptr, (unsigned long)l_tmp->Size, l_tmp->CompilDate,
527 : l_tmp->CompilTime);
528 8734 : l_NbBlocks++;
529 8734 : l_BlockSize += l_tmp->Size;
530 8734 : l_tmp = l_tmp->Next;
531 : }
532 3454 : fprintf(stderr,
533 : "+----------------------+----------------------+------+-----------------+----------+------------------------+\n");
534 3454 : fprintf(stderr,
535 : "| %9lu bytes in %6lu blocks. %70s |\n", (unsigned long)l_BlockSize,
536 : (unsigned long)l_NbBlocks, "");
537 3454 : fprintf(stderr,
538 : "+----------------------------------------------------------------------------------------------------------+\n");
539 : }
540 : /* Add ASSERT or assert (l_NbBlocks==NbBlocks) */
541 7900 : return l_NbBlocks;
542 : }
543 :
544 : /** Get the memory block metadata entries count (postinit)
545 : *
546 : * This function is referenced by the memtrack_addblock functor after
547 : * initialization. This is the real implementation of the feature.
548 : *
549 : * \sa memtrack_getallocatedblocks
550 : * \sa memtrack_getallocatedblocks_preinit
551 : */
552 23505 : static uint64_t memtrack_getallocatedblocks_postinit()
553 : {
554 23505 : return NbBlocks;
555 : }
556 :
557 : /** Get the memory block metadata entries total RAM (postinit)
558 : *
559 : * This function is referenced by the memtrack_addblock functor after
560 : * initialization. This is the real implementation of the feature.
561 : *
562 : * \sa memtrack_getallocatedRAM
563 : * \sa memtrack_getallocatedRAM_preinit
564 : */
565 15997 : static uint64_t memtrack_getallocatedRAM_postinit()
566 : {
567 15997 : return RAMSize;
568 : }
569 :
570 : /** Get a memory block RAM size (postinit)
571 : *
572 : * This function is referenced by the memtrack_addblock functor after
573 : * initialization. This is the real implementation of the feature.
574 : *
575 : * \sa memtrack_getblocksize
576 : * \sa memtrack_getblocksize_preinit
577 : */
578 9974 : static size_t memtrack_getblocksize_postinit(const void *p_Ptr)
579 : {
580 : /* Recherche de la description */
581 9974 : TMemBlock *l_tmp = Head->Next;
582 21896 : while ((l_tmp->Ptr != p_Ptr) && (l_tmp != Tail))
583 11922 : l_tmp = l_tmp->Next;
584 :
585 : /* Le bloc doit avoir été trouvé */
586 9974 : if (l_tmp == Tail)
587 5078 : return 0;
588 : else
589 4896 : return l_tmp->Size;
590 : }
591 :
592 : /* Documented in header file */
593 : unsigned int (*memtrack_addblock) (const void *p_Ptr,
594 : const size_t p_Size,
595 : const char *p_File,
596 : const int p_Line,
597 : const char *p_CompilDate,
598 : const char *p_CompilTime,
599 : const char *p_Function) =
600 : memtrack_addblock_preinit;
601 :
602 : /* Documented in header file */
603 : unsigned int (*memtrack_delblock) (const void *p_Ptr,
604 : const char *p_File,
605 : const int p_Line,
606 : const char *p_CompilDate,
607 : const char *p_CompilTime,
608 : const char *p_Function) =
609 : memtrack_delblock_preinit;
610 :
611 : /* Documented in header file */
612 : uint64_t (*memtrack_dumpblocks) () = memtrack_dumpblocks_preinit;
613 :
614 : /* Documented in header file */
615 : uint64_t (*memtrack_getallocatedblocks) () = memtrack_getallocatedblocks_preinit;
616 :
617 : /* Documented in header file */
618 : uint64_t (*memtrack_getallocatedRAM) () = memtrack_getallocatedRAM_preinit;
619 :
620 : /* Documented in header file */
621 : size_t(*memtrack_getblocksize) (const void *p_Ptr) = memtrack_getblocksize_preinit;
|