]>
jfr.im git - irc/evilnet/x3.git/blob - src/alloc-x3.c
1 /* alloc-x3.c - Debug allocation wrapper
2 * Copyright 2005 srvx Development Team
4 * This file is part of srvx.
6 * x3 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
23 #define ALLOC_MAGIC 0x1acf
24 #define FREE_MAGIC 0xfc1d
25 const char redzone
[] = { '\x03', '\x47', '\x76', '\xc7' };
28 unsigned int file_id
: 8;
29 unsigned int size
: 24;
30 unsigned int line
: 16;
31 unsigned int magic
: 16;
34 static char file_id_map
[256][32];
35 static unsigned int file_ids_used
;
36 unsigned long alloc_count
, alloc_size
;
39 file_id_cmp(const void *a_
, const void *b_
)
41 return strcmp(a_
, b_
);
45 get_file_id(const char *fname
)
49 entry
= bsearch(fname
, file_id_map
, file_ids_used
, sizeof(file_id_map
[0]), file_id_cmp
);
51 return ((char*)entry
- file_id_map
[0]) / sizeof(file_id_map
[0]);
52 strcpy(file_id_map
[file_ids_used
++], fname
);
53 qsort(file_id_map
, file_ids_used
, sizeof(file_id_map
[0]), file_id_cmp
);
54 return file_ids_used
- 1;
58 x3_malloc(const char *file
, unsigned int line
, size_t size
)
60 struct alloc_header
*block
;
62 block
= malloc(sizeof(*block
) + size
+ sizeof(redzone
));
63 assert(block
!= NULL
);
64 if (block
->magic
== ALLOC_MAGIC
&& block
->file_id
< file_ids_used
) {
65 /* Only report the error, due to possible false positives. */
66 log_module(MAIN_LOG
, LOG_WARNING
, "Detected possible reallocation: %p (called by %s:%u/%lu; allocated by %u:%u/%u).",
67 block
, file
, line
, (unsigned long)size
,
68 block
->file_id
, block
->line
, block
->size
);
70 memset(block
, 0, sizeof(*block
) + size
);
71 memcpy((char*)(block
+ 1) + size
, redzone
, sizeof(redzone
));
72 block
->file_id
= get_file_id(file
);
75 block
->magic
= ALLOC_MAGIC
;
82 x3_realloc(const char *file
, unsigned int line
, void *ptr
, size_t size
)
84 struct alloc_header
*block
, *newblock
;
87 return x3_malloc(file
, line
, size
);
90 block
= (struct alloc_header
*)ptr
- 1;
92 if (block
->size
>= size
)
95 newblock
= malloc(sizeof(*newblock
) + size
+ sizeof(redzone
));
96 assert(newblock
!= NULL
);
97 memset(newblock
, 0, sizeof(*newblock
));
98 memcpy(newblock
+ 1, block
+ 1, block
->size
);
99 memset((char*)(newblock
+ 1) + block
->size
, 0, size
- block
->size
);
100 memcpy((char*)(newblock
+ 1) + size
, redzone
, sizeof(redzone
));
101 newblock
->file_id
= get_file_id(file
);
102 newblock
->line
= line
;
103 newblock
->size
= size
;
104 newblock
->magic
= ALLOC_MAGIC
;
108 x3_free(file
, line
, block
+ 1);
114 x3_strdup(const char *file
, unsigned int line
, const char *src
)
119 len
= strlen(src
) + 1;
120 target
= x3_malloc(file
, line
, len
);
121 memcpy(target
, src
, len
);
126 x3_free(UNUSED_ARG(const char *file
), UNUSED_ARG(unsigned int line
), void *ptr
)
128 struct alloc_header
*block
;
134 block
= (struct alloc_header
*)ptr
- 1;
136 memset(block
+ 1, 0xde, size
);
137 block
->magic
= FREE_MAGIC
;
144 verify(const void *ptr
)
146 const struct alloc_header
*header
;
149 header
= (const struct alloc_header
*)ptr
- 1;
150 assert(header
->magic
== ALLOC_MAGIC
);
151 assert(!memcmp((char*)(header
+ 1) + header
->size
, redzone
, sizeof(redzone
)));