Release s3d 0.2.2
[s3d.git] / server / allocate.c
blobcfd96e5922181f5696a763440de38bf76dc36b2a
1 /*
2 * allocate.c
4 * Copyright (C) 2006-2011 Marek Lindner <lindner_marek@yahoo.de>
5 * Copyright (C) 2006-2011 Simon Wunderlich <dotslash@packetmixer.de>
7 * This file is part of s3d, a 3d network display server.
8 * See http://s3d.berlios.de/ for more updates.
10 * s3d is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * s3d is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with s3d; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 /* this file is taken from the batman project (www.open-mesh.net/batman)
26 * to find heap corruptions... */
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include "allocate.h"
34 #define DEBUG_MALLOC
36 #define MAGIC_NUMBER 0x12345678
38 #if defined DEBUG_MALLOC
40 static struct chunkHeader *chunkList = NULL;
42 struct chunkHeader {
43 struct chunkHeader *next;
44 unsigned int length;
45 int tag;
46 unsigned int magicNumber;
49 struct chunkTrailer {
50 unsigned int magicNumber;
53 void checkIntegrity(void)
55 struct chunkHeader *walker;
56 struct chunkTrailer *chunkTrailer;
57 unsigned char *memory;
59 for (walker = chunkList; walker != NULL; walker = walker->next) {
60 if (walker->magicNumber != MAGIC_NUMBER) {
61 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", walker->magicNumber, walker->tag);
62 exit(1);
65 memory = (unsigned char *)walker;
67 chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + walker->length);
69 if (chunkTrailer->magicNumber != MAGIC_NUMBER) {
70 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", chunkTrailer->magicNumber, walker->tag);
71 exit(1);
76 void checkLeak(void)
78 struct chunkHeader *walker;
80 for (walker = chunkList; walker != NULL; walker = walker->next)
81 fprintf(stderr, "Memory leak detected, tag = %d\n", walker->tag);
84 void *debugMalloc(unsigned int length, int tag)
86 unsigned char *memory;
87 struct chunkHeader *chunkHeader;
88 struct chunkTrailer *chunkTrailer;
89 unsigned char *chunk;
91 checkIntegrity();
93 memory = (unsigned char *)malloc(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer));
95 if (memory == NULL) {
96 fprintf(stderr, "Cannot allocate %u bytes, tag = %d\n", (unsigned int)(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer)), tag);
97 exit(1);
100 chunkHeader = (struct chunkHeader *)memory;
101 chunk = memory + sizeof(struct chunkHeader);
102 chunkTrailer = (struct chunkTrailer *)(memory + sizeof(struct chunkHeader) + length);
104 chunkHeader->length = length;
105 chunkHeader->tag = tag;
106 chunkHeader->magicNumber = MAGIC_NUMBER;
108 chunkTrailer->magicNumber = MAGIC_NUMBER;
110 chunkHeader->next = chunkList;
111 chunkList = chunkHeader;
113 return chunk;
116 void *debugRealloc(void *memoryParameter, unsigned int length, int tag)
118 unsigned char *memory;
119 struct chunkHeader *chunkHeader;
120 struct chunkTrailer *chunkTrailer;
121 unsigned char *result;
122 unsigned int copyLength;
124 checkIntegrity();
126 if (memoryParameter) { /* if memoryParameter==NULL, realloc() should work like malloc() !! */
127 memory = (unsigned char *)memoryParameter;
128 chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
130 if (chunkHeader->magicNumber != MAGIC_NUMBER) {
131 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag);
132 exit(1);
135 chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
137 if (chunkTrailer->magicNumber != MAGIC_NUMBER) {
138 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag);
139 exit(1);
143 result = (unsigned char *)debugMalloc(length, tag);
144 if (memoryParameter) {
145 copyLength = length;
147 if (copyLength > chunkHeader->length)
148 copyLength = chunkHeader->length;
150 memcpy(result, memoryParameter, copyLength);
151 debugFree(memoryParameter);
154 return result;
157 void debugFree(void *memoryParameter)
159 unsigned char *memory;
160 struct chunkHeader *chunkHeader;
161 struct chunkTrailer *chunkTrailer;
162 struct chunkHeader *walker;
163 struct chunkHeader *previous;
165 checkIntegrity();
167 memory = (unsigned char *)memoryParameter;
168 chunkHeader = (struct chunkHeader *)(memory - sizeof(struct chunkHeader));
170 if (chunkHeader->magicNumber != MAGIC_NUMBER) {
171 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag);
172 exit(1);
175 previous = NULL;
177 for (walker = chunkList; walker != NULL; walker = walker->next) {
178 if (walker == chunkHeader)
179 break;
181 previous = walker;
184 if (walker == NULL) {
185 fprintf(stderr, "Double free detected, tag = %d\n", chunkHeader->tag);
186 exit(1);
189 if (previous == NULL)
190 chunkList = walker->next;
192 else
193 previous->next = walker->next;
195 chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
197 if (chunkTrailer->magicNumber != MAGIC_NUMBER) {
198 fprintf(stderr, "Invalid magic number in header: %08x, tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag);
199 exit(1);
202 free(chunkHeader);
205 #else
207 void checkIntegrity(void)
211 void checkLeak(void)
215 void *debugMalloc(unsigned int length, int tag)
217 void *result;
219 result = malloc(length);
221 if (result == NULL) {
222 fprintf(stderr, "Cannot allocate %u bytes, tag = %d\n", length, tag);
223 exit(1);
226 return result;
229 void *debugRealloc(void *memory, unsigned int length, int tag)
231 void *result;
233 result = realloc(memory, length);
235 if (result == NULL) {
236 fprintf(stderr, "Cannot re-allocate %u bytes, tag = %d\n", length, tag);
237 exit(1);
240 return result;
243 void debugFree(void *memory)
245 free(memory);
248 #endif