2
* Copyright (C) 2006 B.A.T.M.A.N. contributors:
3
* Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of version 2 of the GNU General Public
6
* License as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30
/* #define DEBUG_MALLOC */
31
/* #define MEMORY_USAGE */
33
#define MAGIC_NUMBER 0x12345678
35
#if defined DEBUG_MALLOC
37
struct chunkHeader *chunkList = NULL;
41
struct chunkHeader *next;
54
#if defined MEMORY_USAGE
56
struct memoryUsage *memoryList = NULL;
61
struct memoryUsage *next;
68
void addMemory( uint32_t length, int32_t tag ) {
70
struct memoryUsage *walker;
73
for ( walker = memoryList; walker != NULL; walker = walker->next ) {
75
if ( walker->tag == tag ) {
84
if ( walker == NULL ) {
86
walker = malloc( sizeof(struct memoryUsage) );
88
walker->length = length;
92
walker->next = memoryList;
100
void removeMemory( int32_t tag, int32_t freetag ) {
102
struct memoryUsage *walker;
105
for ( walker = memoryList; walker != NULL; walker = walker->next ) {
107
if ( walker->tag == tag ) {
109
if ( walker->counter == 0 ) {
111
debug_output( 0, "Freeing more memory than was allocated: malloc tag = %d, free tag = %d\n", tag, freetag );
123
if ( walker == NULL ) {
125
debug_output( 0, "Freeing memory that was never allocated: malloc tag = %d, free tag = %d\n", tag, freetag );
136
void checkIntegrity(void)
138
struct chunkHeader *walker;
139
struct chunkTrailer *chunkTrailer;
140
unsigned char *memory;
143
#if defined MEMORY_USAGE
145
struct memoryUsage *memoryWalker;
147
debug_output( 3, " \nMemory usage information:\n" );
149
for ( memoryWalker = memoryList; memoryWalker != NULL; memoryWalker = memoryWalker->next ) {
151
if ( memoryWalker->counter != 0 )
152
debug_output( 3, " tag: %4i, num malloc: %4i, bytes per malloc: %4i, total: %6i\n", memoryWalker->tag, memoryWalker->counter, memoryWalker->length, memoryWalker->counter * memoryWalker->length );
159
for (walker = chunkList; walker != NULL; walker = walker->next)
161
if (walker->magicNumber != MAGIC_NUMBER)
163
debug_output( 0, "checkIntegrity - invalid magic number in header: %08x, malloc tag = %d\n", walker->magicNumber, walker->tag );
167
memory = (unsigned char *)walker;
169
chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + walker->length);
171
if (chunkTrailer->magicNumber != MAGIC_NUMBER)
173
debug_output( 0, "checkIntegrity - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, walker->tag );
181
struct chunkHeader *walker;
183
for (walker = chunkList; walker != NULL; walker = walker->next)
184
debug_output( 0, "Memory leak detected, malloc tag = %d\n", walker->tag );
187
void *debugMalloc(uint32_t length, int32_t tag)
189
unsigned char *memory;
190
struct chunkHeader *chunkHeader;
191
struct chunkTrailer *chunkTrailer;
192
unsigned char *chunk;
194
// printf("sizeof(struct chunkHeader) = %u, sizeof (struct chunkTrailer) = %u\n", sizeof (struct chunkHeader), sizeof (struct chunkTrailer));
196
memory = malloc(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer));
200
debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", (unsigned int)(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer)), tag );
204
chunkHeader = (struct chunkHeader *)memory;
205
chunk = memory + sizeof(struct chunkHeader);
206
chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + length);
208
chunkHeader->length = length;
209
chunkHeader->tag = tag;
210
chunkHeader->magicNumber = MAGIC_NUMBER;
212
chunkTrailer->magicNumber = MAGIC_NUMBER;
214
chunkHeader->next = chunkList;
215
chunkList = chunkHeader;
217
#if defined MEMORY_USAGE
219
addMemory( length, tag );
226
void *debugRealloc(void *memoryParameter, uint32_t length, int32_t tag)
228
unsigned char *memory;
229
struct chunkHeader *chunkHeader;
230
struct chunkTrailer *chunkTrailer;
231
unsigned char *result;
234
if (memoryParameter) { /* if memoryParameter==NULL, realloc() should work like malloc() !! */
235
memory = memoryParameter;
236
chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
238
if (chunkHeader->magicNumber != MAGIC_NUMBER)
240
debug_output( 0, "debugRealloc - invalid magic number in header: %08x, malloc tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag );
244
chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
246
if (chunkTrailer->magicNumber != MAGIC_NUMBER)
248
debug_output( 0, "debugRealloc - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag );
254
result = debugMalloc(length, tag);
255
if (memoryParameter) {
258
if (copyLength > chunkHeader->length)
259
copyLength = chunkHeader->length;
261
memcpy(result, memoryParameter, copyLength);
262
debugFree(memoryParameter, 9999);
269
void debugFree(void *memoryParameter, int tag)
271
unsigned char *memory;
272
struct chunkHeader *chunkHeader;
273
struct chunkTrailer *chunkTrailer;
274
struct chunkHeader *walker;
275
struct chunkHeader *previous;
277
memory = memoryParameter;
278
chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
280
if (chunkHeader->magicNumber != MAGIC_NUMBER)
282
debug_output( 0, "debugFree - invalid magic number in header: %08x, malloc tag = %d, free tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag, tag );
288
for (walker = chunkList; walker != NULL; walker = walker->next)
290
if (walker == chunkHeader)
298
debug_output( 0, "Double free detected, malloc tag = %d, free tag = %d\n", chunkHeader->tag, tag );
302
if (previous == NULL)
303
chunkList = walker->next;
306
previous->next = walker->next;
308
chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
310
if (chunkTrailer->magicNumber != MAGIC_NUMBER)
312
debug_output( 0, "debugFree - invalid magic number in trailer: %08x, malloc tag = %d, free tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag, tag );
316
#if defined MEMORY_USAGE
318
removeMemory( chunkHeader->tag, tag );
328
void checkIntegrity(void)
336
void *debugMalloc(uint32_t length, int32_t tag)
340
result = malloc(length);
344
debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", length, tag );
351
void *debugRealloc(void *memory, uint32_t length, int32_t tag)
355
result = realloc(memory, length);
359
debug_output( 0, "Cannot re-allocate %u bytes, malloc tag = %d\n", length, tag );
366
void debugFree(void *memory, int32_t tag)