File: memalloc.h

package info (click to toggle)
libconvert-binary-c-perl 0.74-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 9,100 kB
  • ctags: 21,416
  • sloc: ansic: 63,666; perl: 18,582; yacc: 2,143; makefile: 44
file content (414 lines) | stat: -rw-r--r-- 13,774 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
/*******************************************************************************
*
* HEADER: memalloc
*
********************************************************************************
*
* DESCRIPTION: Memory allocation and tracing routines
*
********************************************************************************
*
* $Project: /Convert-Binary-C $
* $Author: mhx $
* $Date: 2009/03/15 04:10:45 +0100 $
* $Revision: 28 $
* $Source: /util/memalloc.h $
*
********************************************************************************
*
* Copyright (c) 2002-2009 Marcus Holland-Moritz. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of either the Artistic License or the
* GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*******************************************************************************/

/**
 *  \file memalloc.h
 *  \brief Memory allocation and tracing routines
 *
 *  The functions in this file provide an interface to
 *  the standard malloc / free functions, but in addition
 *  you can selectively enable tracing of your memory
 *  allocation. This may be useful to detect memory leaks
 *  or usage of already freed memory blocks.
 *
 *  A Perl script is supplied to analyze the output of
 *  the memory tracing routines.
 *
 *  To enable the tracing capability, the library must be
 *  compiled with the #DEBUG_MEMALLOC preprocessor flag. Then,
 *  you can selectively enable the tracing for each file or
 *  project by using the SetDebugMemAlloc() routine.
 *
 *  The following code shows an example:
 *
 *  \include Alloc.c
 *
 *  Then, a file like this will be written to stdout:
 *
 *  \verbinclude mem_debug.dat
 *
 *  This output is easy to understand. It tells you that
 *
 *  -# in file \c Alloc.c, line 9, there were 16 bytes allocated at address 0x400031C0,
 *  -# in file \c Alloc.c, line 10, address 0x400031C0 was verified,
 *  -# in file \c Alloc.c, line 11, the memory block at address 0x400031C0 was freed,
 *  -# in file \c Alloc.c, line 12, address 0x400031C0 was verified again.
 *
 *  These files usually become very large if you work a lot with
 *  dynamic memory allocation. So it would be rather hard to step
 *  through that file on your own. For that reason, there's a Perl
 *  script called \c check_alloc.pl that will take \c mem_debug.dat
 *  as input and print all errors discovered and summary statistics:
 *
 *  \verbinclude mem_debug.out
 *
 *  As you can see, the last call to AssertValidPtr() caused an error
 *  because the block that was checked has already been freed. The
 *  other output is only useful if you have lots of dynamic memory
 *  allocation, for example:
 *
 *  \verbinclude memdb_large.out
 *
 *  This will tell you that a total of 32404 memory blocks have been
 *  successfully allocated and freed, a maximum of 13305 memory blocks
 *  were in use simultanously, the peak memory usage was 183675 bytes,
 *  the smallest and largest block that were allocated were 2 and 29
 *  bytes in size, respectively, and there were no memory leaks detected.
 *
 */
#ifndef _UTIL_MEMALLOC_H
#define _UTIL_MEMALLOC_H

#include <stdio.h>

#ifdef UTIL_HAVE_CONFIG_H
# include "config.h"
#endif

#if !(defined(UTIL_MALLOC) && defined(UTIL_CALLOC) && defined(UTIL_REALLOC) && defined(UTIL_FREE))
# include <stdlib.h>
# define UTIL_MALLOC(size)          malloc(size)
# define UTIL_CALLOC(count, size)   calloc(count, size)
# define UTIL_REALLOC(ptr, size)    realloc(ptr, size)
# define UTIL_FREE(ptr)             free(ptr)
#endif

#define DB_MEMALLOC_TRACE    0x00000001
#define DB_MEMALLOC_ASSERT   0x00000002

#ifdef DEBUG_MEMALLOC
void *_memAlloc( size_t size, const char *file, int line );
void *_memCAlloc( size_t nobj, size_t size, const char *file, int line );
void *_memReAlloc( void *p, size_t size, const char *file, int line );
void  _memFree( void *p, const char *file, int line );
void  _assertValidPtr( const void *p, const char *file, int line );
void  _assertValidBlock( const void *p, size_t size, const char *file, int line );
int    SetDebugMemAlloc( void (*dbfunc)(const char *, ...), unsigned long dbflags );
#else
void *_memAlloc( size_t size );
void *_memCAlloc( size_t nobj, size_t size );
void *_memReAlloc( void *p, size_t size );
void  _memFree( void *p );
#endif

/***************************************************************/
/*                       DOCUMENTATION                         */
/***************************************************************/

#ifdef DOXYGEN

/**
 *  Make memory allocation routines abort when out of memory
 *
 *  Set this preprocessor flag if you want the Alloc(), CAlloc()
 *  and ReAlloc() functions as well as the fast macros AllocF(),
 *  CAllocF() and ReAllocF() to abort if the system runs out of
 *  memory.
 */

#define ABORT_IF_NO_MEM

/**
 *  Compile with debugging support
 */

#define DEBUG_MEMALLOC

/**
 *  Compile with tracing / leak detection support
 *
 *  This may slow down memory allocation if lots of blocks
 *  are simultaneously allocted. It will also increase the
 *  memory requirements of your application.
 *
 *  On the plus side, you get run-time memory allocation tracing,
 *  assertion checking, leak detection and memory statistics.
 *  You can control the amount of statistics by setting the
 *  MEMALLOC_STAT_LEVEL environment variable to a value between
 *  0 and 3, with increasing amount of output.
 *
 *  If an assertion fails, the program will usually abort.
 *  You can choose not to abort the program by setting
 *  MEMALLOC_SOFT_ASSERT to a non-zero value in your
 *  environment.
 *
 *  If you want the memory allocator to keep information about
 *  freed blocks, set MEMALLOC_CHECK_FREED to a non-zero value.
 *  This can give more detailed trace output at the cost of
 *  slower execution.
 *
 *  If you like to see hex dumps of non-freed memory blocks,
 *  you can set MEMALLOC_SHOW_DUMPS to a non-zero value.
 *
 *  Only works if DEBUG_MEMALLOC is also defined.
 */

#define TRACE_MEMALLOC

/**
 *  Build with memory allocator that automatically purges
 *  allocated / freed memory blocks.
 *
 *  Only works if DEBUG_MEMALLOC is also defined.
 */

#define AUTOPURGE_MEMALLOC

/**
 *  Build without support for the Alloc(), CAlloc() and
 *  ReAlloc() functions. Memory management is completely
 *  carried out through the use of the fast allocation
 *  macros AllocF(), CAllocF() and ReAllocF().
 */

#define NO_SLOW_MEMALLOC_CALLS

/**
 *  Allocate a memory block
 *
 *  Allocates a memory block of \a size bytes. If the files
 *  were compiled with the #ABORT_IF_NO_MEM preprocessor flag,
 *  the function aborts if no memory can be allocated.
 *
 *  \param size           Size of the memory block in bytes.
 *
 *  \return A pointer to the allocated memory block, or NULL
 *          if memory couldn't be allocated.
 */

void *Alloc( size_t size );

/**
 *  Allocate a memory block and initialize to zero
 *
 *  Allocates a memory block to hold \a nobj times
 *  \a size bytes. If the files were compiled with the
 *  #ABORT_IF_NO_MEM preprocessor flag, the function
 *  aborts if no memory can be allocated.
 *
 *  \param nobj           Number of objects.
 *
 *  \param size           Size of one object in bytes.
 *
 *  \return A pointer to the allocated memory block, or NULL
 *          if memory couldn't be allocated.
 */

void *CAlloc( size_t nobj, size_t size );

/**
 *  Reallocate a memory block
 *
 *  Reallocates a memory block of \a size bytes. If the files
 *  were compiled with the #ABORT_IF_NO_MEM preprocessor flag,
 *  the function aborts if no memory can be allocated.
 *
 *  \param ptr            Pointer to an allocated memory block.
 *
 *  \param size           Size of new memory block in bytes.
 *
 *  \return A pointer to the reallocated memory block, or NULL
 *          if memory couldn't be reallocated.
 */

void *ReAlloc( void *ptr, size_t size );

/**
 *  Fast Alloc Macro
 *
 *  Allocates a memory block of \a size bytes. If the files
 *  were compiled with the #ABORT_IF_NO_MEM preprocessor flag,
 *  the function aborts if no memory can be allocated.
 *
 *  \param cast           Pointer cast.
 *
 *  \param ptr            Pointer to memory block.
 *
 *  \param size           Size of the memory block in bytes.
 */

#define AllocF( cast, ptr, size )

/**
 *  Fast CAlloc Macro
 *
 *  Allocates a memory block to hold \a nobj times
 *  \a size bytes. If the files were compiled with the
 *  #ABORT_IF_NO_MEM preprocessor flag, the function
 *  aborts if no memory can be allocated.
 *
 *  \param cast           Pointer cast.
 *
 *  \param ptr            Pointer to memory block.
 *
 *  \param nobj           Number of objects.
 *
 *  \param size           Size of one object in bytes.
 */

#define CAllocF( cast, ptr, nobj, size )

/**
 *  Fast ReAlloc Macro
 *
 *  Reallocates a memory block of \a size bytes. If the files
 *  were compiled with the #ABORT_IF_NO_MEM preprocessor flag,
 *  the function aborts if no memory can be allocated.
 *
 *  \param cast           Pointer cast.
 *
 *  \param ptr            Pointer to memory block.
 *
 *  \param size           Size of new memory block in bytes.
 */

#define ReAllocF( cast, ptr, size )

/**
 *  Free a memory block
 *
 *  Frees a memory block that has been previously allocated
 *  using the Alloc() function.
 *
 *  \param ptr            Pointer to a previously allocated
 *                        memory block.
 */

void Free( void *ptr );

/**
 *  Trace pointer access.
 *
 *  This may prove useful for checking if \a ptr points to
 *  an existing, previously allocated, not yet freed memory
 *  block.
 *
 *  \param ptr            Pointer to be traced.
 */

void AssertValidPtr( void *ptr );

/**
 *  Trace memory block access.
 *
 *  Allows checking if a certain memory block lies within
 *  a previously allocated memory block.
 *
 *  \param ptr            Pointer to memory block.
 *
 *  \param size           Size of memory block.
 */

void AssertValidBlock( void *ptr, size_t size );

/**
 *  Configure debugging support.
 *
 *  \param dbfunc         Pointer to a printf() like function
 *                        for writing the debug output.
 *
 *  \param dbflags        Binary ORed debugging flags. Currently,
 *                        you can request memory allocation tracing
 *                        with \c DB_MEMALLOC_TRACE and pointer
 *                        assertions with \c DB_MEMALLOC_ASSERT.
 */

int SetDebugMemAlloc( void (*dbfunc)(char *, ...), unsigned long dbflags );

#else /* !DOXYGEN */

/***************************************************************/
/*                    END OF DOCUMENTATION                     */
/***************************************************************/

#ifdef ABORT_IF_NO_MEM
# define abortMEMALLOC( call, size, expr )                                     \
        do {                                                                   \
          if( (expr) == NULL && size > 0 ) {                                   \
            fprintf(stderr, "%s(%d): out of memory!\n", call, size);           \
            abort();                                                           \
          }                                                                    \
        } while(0)
#else
# define abortMEMALLOC( call, size, expr )  do { (void) (expr); } while(0)
#endif

#ifdef DEBUG_MEMALLOC

# ifndef NO_SLOW_MEMALLOC_CALLS
#  define ReAlloc( ptr, size )           _memReAlloc( ptr, size, __FILE__, __LINE__ )
#  define CAlloc( nobj, size )           _memCAlloc( nobj, size, __FILE__, __LINE__ )
#  define Alloc( size )                  _memAlloc( size, __FILE__, __LINE__ )
# endif

# define Free( ptr )                     _memFree( ptr, __FILE__, __LINE__ )
# define AssertValidPtr( ptr )           _assertValidPtr( ptr, __FILE__, __LINE__ )
# define AssertValidBlock( ptr, size )   _assertValidBlock( ptr, size, __FILE__, __LINE__ )

# define ReAllocF( cast, ptr, size ) \
          do { ptr = (cast) _memReAlloc( ptr, size, __FILE__, __LINE__ ); } while(0)
# define CAllocF( cast, ptr, nobj, size ) \
          do { ptr = (cast) _memCAlloc( nobj, size, __FILE__, __LINE__ ); } while(0)
# define AllocF( cast, ptr, size ) \
          do { ptr = (cast) _memAlloc( size, __FILE__, __LINE__ ); } while(0)

#else /* !DEBUG_MEMALLOC */

# ifndef NO_SLOW_MEMALLOC_CALLS
#  ifdef ABORT_IF_NO_MEM
#   define ReAlloc( ptr, size )          _memReAlloc( ptr, size )
#   define CAlloc( nobj, size )          _memCAlloc( nobj, size )
#   define Alloc( size )                 _memAlloc( size )
#  else
#   define ReAlloc( ptr, size )          UTIL_REALLOC( ptr, size )
#   define CAlloc( nobj, size )          UTIL_CALLOC( nobj, size )
#   define Alloc( size )                 UTIL_MALLOC( size )
#  endif
# endif

# define Free( ptr )                     do { if( ptr ) UTIL_FREE( ptr ); } while(0)
# define AssertValidPtr( ptr )           (void) 0
# define AssertValidBlock( ptr, size )   (void) 0
# define SetDebugMemAlloc( func, flags ) 0

# define ReAllocF( cast, ptr, size ) \
           abortMEMALLOC( "ReAllocF", size, ptr = (cast) UTIL_REALLOC( ptr, size ) )
# define CAllocF( cast, ptr, nobj, size ) \
           abortMEMALLOC( "CAllocF", nobj*size, ptr = (cast) UTIL_CALLOC( nobj, size ) )
# define AllocF( cast, ptr, size ) \
           abortMEMALLOC( "AllocF", size, ptr = (cast) UTIL_MALLOC( size ) )

#endif /* DEBUG_MEMALLOC */

#endif /* DOXYGEN */

#endif