Go to the source code of this file.
Data Structures | |
struct | debug_memory_header |
struct | debug_memory_footer |
Defines | |
#define | DEBUG_MEMORY_MAGIC 0x6e34090aU |
#define | real_malloc(_size) malloc(_size) |
#define | real_free(_ptr) free(_ptr) |
Functions | |
static struct debug_memory_header * | header_from_data (void *data) |
static void * | data_from_header (struct debug_memory_header *hdr) |
static struct debug_memory_footer * | footer_from_header (struct debug_memory_header *hdr) |
void * | debug_malloc (const char *file, unsigned line, const char *function, size_t size) |
void | debug_free (const char *file, unsigned line, const char *function, void *ptr) |
void * | debug_calloc (const char *file, unsigned line, const char *function, size_t count, size_t size) |
void * | debug_realloc (const char *file, unsigned line, const char *function, void *old_ptr, size_t old_size, size_t new_size) |
unsigned long | debug_memory_begin (void) |
void | debug_memory_end (unsigned long start_no) |
Variables | |
static struct list_head | list = { &list, &list } |
static unsigned long | last_no = 0 |
Definition in file p_debug_mem.c.
#define DEBUG_MEMORY_MAGIC 0x6e34090aU |
Definition at line 51 of file p_debug_mem.c.
#define real_free | ( | _ptr | ) | free(_ptr) |
Definition at line 62 of file p_debug_mem.c.
#define real_malloc | ( | _size | ) | malloc(_size) |
Definition at line 61 of file p_debug_mem.c.
static void* data_from_header | ( | struct debug_memory_header * | hdr | ) | [static] |
Definition at line 99 of file p_debug_mem.c.
00100 { 00101 if(hdr) 00102 return (void *)((char *)hdr + sizeof(struct debug_memory_header)); 00103 else 00104 return NULL; 00105 }
void* debug_calloc | ( | const char * | file, | |
unsigned | line, | |||
const char * | function, | |||
size_t | count, | |||
size_t | size | |||
) |
Definition at line 184 of file p_debug_mem.c.
References debug_malloc().
00186 { 00187 void *ptr = debug_malloc( file, line, function, count * size ); 00188 if( ptr ) 00189 memset( ptr, 0, count * size ); 00190 return ptr; 00191 }
void debug_free | ( | const char * | file, | |
unsigned | line, | |||
const char * | function, | |||
void * | ptr | |||
) |
Definition at line 150 of file p_debug_mem.c.
References debug_assert, DEBUG_MEMORY_MAGIC, debug_printf(), debug_memory_header::file, footer_from_header(), debug_memory_header::function, debug_memory_header::head, header_from_data(), debug_memory_header::line, LIST_DEL, debug_memory_footer::magic, debug_memory_header::magic, and real_free.
00152 { 00153 struct debug_memory_header *hdr; 00154 struct debug_memory_footer *ftr; 00155 00156 if(!ptr) 00157 return; 00158 00159 hdr = header_from_data(ptr); 00160 if(hdr->magic != DEBUG_MEMORY_MAGIC) { 00161 debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", 00162 file, line, function, 00163 ptr); 00164 debug_assert(0); 00165 return; 00166 } 00167 00168 ftr = footer_from_header(hdr); 00169 if(ftr->magic != DEBUG_MEMORY_MAGIC) { 00170 debug_printf("%s:%u:%s: buffer overflow %p\n", 00171 hdr->file, hdr->line, hdr->function, 00172 ptr); 00173 debug_assert(0); 00174 } 00175 00176 LIST_DEL(&hdr->head); 00177 hdr->magic = 0; 00178 ftr->magic = 0; 00179 00180 real_free(hdr); 00181 }
void* debug_malloc | ( | const char * | file, | |
unsigned | line, | |||
const char * | function, | |||
size_t | size | |||
) |
Definition at line 118 of file p_debug_mem.c.
References assert, data_from_header(), DEBUG_MEMORY_MAGIC, debug_printf(), debug_memory_header::file, footer_from_header(), debug_memory_header::function, debug_memory_header::head, last_no, debug_memory_header::line, LIST_ADDTAIL, debug_memory_footer::magic, debug_memory_header::magic, debug_memory_header::no, real_malloc, and debug_memory_header::size.
00120 { 00121 struct debug_memory_header *hdr; 00122 struct debug_memory_footer *ftr; 00123 00124 assert(size); 00125 00126 hdr = real_malloc(sizeof(*hdr) + size + sizeof(*ftr)); 00127 if(!hdr) { 00128 debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", 00129 file, line, function, 00130 (long unsigned)size); 00131 return NULL; 00132 } 00133 00134 hdr->no = last_no++; 00135 hdr->file = file; 00136 hdr->line = line; 00137 hdr->function = function; 00138 hdr->size = size; 00139 hdr->magic = DEBUG_MEMORY_MAGIC; 00140 00141 ftr = footer_from_header(hdr); 00142 ftr->magic = DEBUG_MEMORY_MAGIC; 00143 00144 LIST_ADDTAIL(&hdr->head, &list); 00145 00146 return data_from_header(hdr); 00147 }
unsigned long debug_memory_begin | ( | void | ) |
Definition at line 259 of file p_debug_mem.c.
References last_no.
00260 { 00261 return last_no; 00262 }
void debug_memory_end | ( | unsigned long | start_no | ) |
Definition at line 265 of file p_debug_mem.c.
References data_from_header(), debug_assert, DEBUG_MEMORY_MAGIC, debug_printf(), debug_memory_header::file, footer_from_header(), debug_memory_header::function, last_no, debug_memory_header::line, LIST_ENTRY, debug_memory_footer::magic, debug_memory_header::magic, debug_memory_header::no, list_head::prev, and debug_memory_header::size.
00266 { 00267 size_t total_size = 0; 00268 struct list_head *entry; 00269 00270 if(start_no == last_no) 00271 return; 00272 00273 entry = list.prev; 00274 for (; entry != &list; entry = entry->prev) { 00275 struct debug_memory_header *hdr; 00276 void *ptr; 00277 struct debug_memory_footer *ftr; 00278 00279 hdr = LIST_ENTRY(struct debug_memory_header, entry, head); 00280 ptr = data_from_header(hdr); 00281 ftr = footer_from_header(hdr); 00282 00283 if(hdr->magic != DEBUG_MEMORY_MAGIC) { 00284 debug_printf("%s:%u:%s: bad or corrupted memory %p\n", 00285 hdr->file, hdr->line, hdr->function, 00286 ptr); 00287 debug_assert(0); 00288 } 00289 00290 if((start_no <= hdr->no && hdr->no < last_no) || 00291 (last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) { 00292 debug_printf("%s:%u:%s: %u bytes at %p not freed\n", 00293 hdr->file, hdr->line, hdr->function, 00294 hdr->size, ptr); 00295 total_size += hdr->size; 00296 } 00297 00298 if(ftr->magic != DEBUG_MEMORY_MAGIC) { 00299 debug_printf("%s:%u:%s: buffer overflow %p\n", 00300 hdr->file, hdr->line, hdr->function, 00301 ptr); 00302 debug_assert(0); 00303 } 00304 } 00305 00306 if(total_size) { 00307 debug_printf("Total of %u KB of system memory apparently leaked\n", 00308 (total_size + 1023)/1024); 00309 } 00310 else { 00311 debug_printf("No memory leaks detected.\n"); 00312 } 00313 }
void* debug_realloc | ( | const char * | file, | |
unsigned | line, | |||
const char * | function, | |||
void * | old_ptr, | |||
size_t | old_size, | |||
size_t | new_size | |||
) |
Definition at line 194 of file p_debug_mem.c.
References data_from_header(), debug_assert, debug_free(), debug_malloc(), DEBUG_MEMORY_MAGIC, debug_printf(), debug_memory_header::file, footer_from_header(), debug_memory_header::function, debug_memory_header::head, header_from_data(), debug_memory_header::line, LIST_REPLACE, debug_memory_footer::magic, debug_memory_header::magic, debug_memory_header::no, real_free, real_malloc, and debug_memory_header::size.
00196 { 00197 struct debug_memory_header *old_hdr, *new_hdr; 00198 struct debug_memory_footer *old_ftr, *new_ftr; 00199 void *new_ptr; 00200 00201 if(!old_ptr) 00202 return debug_malloc( file, line, function, new_size ); 00203 00204 if(!new_size) { 00205 debug_free( file, line, function, old_ptr ); 00206 return NULL; 00207 } 00208 00209 old_hdr = header_from_data(old_ptr); 00210 if(old_hdr->magic != DEBUG_MEMORY_MAGIC) { 00211 debug_printf("%s:%u:%s: reallocating bad or corrupted memory %p\n", 00212 file, line, function, 00213 old_ptr); 00214 debug_assert(0); 00215 return NULL; 00216 } 00217 00218 old_ftr = footer_from_header(old_hdr); 00219 if(old_ftr->magic != DEBUG_MEMORY_MAGIC) { 00220 debug_printf("%s:%u:%s: buffer overflow %p\n", 00221 old_hdr->file, old_hdr->line, old_hdr->function, 00222 old_ptr); 00223 debug_assert(0); 00224 } 00225 00226 /* alloc new */ 00227 new_hdr = real_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); 00228 if(!new_hdr) { 00229 debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", 00230 file, line, function, 00231 (long unsigned)new_size); 00232 return NULL; 00233 } 00234 new_hdr->no = old_hdr->no; 00235 new_hdr->file = old_hdr->file; 00236 new_hdr->line = old_hdr->line; 00237 new_hdr->function = old_hdr->function; 00238 new_hdr->size = new_size; 00239 new_hdr->magic = DEBUG_MEMORY_MAGIC; 00240 00241 new_ftr = footer_from_header(new_hdr); 00242 new_ftr->magic = DEBUG_MEMORY_MAGIC; 00243 00244 LIST_REPLACE(&old_hdr->head, &new_hdr->head); 00245 00246 /* copy data */ 00247 new_ptr = data_from_header(new_hdr); 00248 memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size ); 00249 00250 /* free old */ 00251 old_hdr->magic = 0; 00252 old_ftr->magic = 0; 00253 real_free(old_hdr); 00254 00255 return new_ptr; 00256 }
static struct debug_memory_footer* footer_from_header | ( | struct debug_memory_header * | hdr | ) | [static, read] |
Definition at line 108 of file p_debug_mem.c.
References debug_memory_header::size.
00109 { 00110 if(hdr) 00111 return (struct debug_memory_footer *)((char *)hdr + sizeof(struct debug_memory_header) + hdr->size); 00112 else 00113 return NULL; 00114 }
static struct debug_memory_header* header_from_data | ( | void * | data | ) | [static, read] |
Definition at line 90 of file p_debug_mem.c.
00091 { 00092 if(data) 00093 return (struct debug_memory_header *)((char *)data - sizeof(struct debug_memory_header)); 00094 else 00095 return NULL; 00096 }
unsigned long last_no = 0 [static] |
Definition at line 86 of file p_debug_mem.c.