static void lib_debug_libc_free(void *ptr) { #if LIB_DEBUG_GUARD > 0 if (ptr != NULL) { lib_debug_guard_remove((char *)ptr); free((char *)ptr - LIB_DEBUG_GUARD); } else { #ifdef LIB_DEBUG_PINPOINT printf("%s:%d: ", lib_debug_pinpoint_filename, lib_debug_pinpoint_line); #endif printf("Warning: Pointer passed to lib_debug_libc_free is NULL.\n"); } #else free(ptr); #endif }
void lib_debug_check(void) { #ifdef LIB_DEBUG unsigned int index, count; unsigned int leakbytes; count = 0; leakbytes = 0; for (index = 0; index < LIB_DEBUG_SIZE; index++) { if (lib_debug_address[index] != NULL) { count++; #ifdef LIB_DEBUG_PINPOINT printf("%s:%d: ", lib_debug_filename[index], lib_debug_line[index]); #endif printf("Warning: Memory block allocated here was not free'd (Memory leak with size 0x%x at %p).", lib_debug_size[index], lib_debug_address[index]); #ifdef LIB_DEBUG_CALLER printf("(called from %p)", lib_debug_caller[index]); #endif printf("\n"); leakbytes += lib_debug_size[index]; #if LIB_DEBUG_GUARD > 0 lib_debug_guard_remove((char *)lib_debug_address[index]); #endif } } printf("Total memory leaks: %d Bytes leaked: 0x%x\n", count, leakbytes); printf("max. total memory that was allocated: 0x%x bytes. (", lib_debug_max_total); printsize(lib_debug_max_total); printf(")\n"); #ifdef LIB_DEBUG_PINPOINT printf("\nTop %d largest allocated blocks:\n", LIB_DEBUG_TOPMAX); for (index = 0; index < LIB_DEBUG_TOPMAX; index++) { if (lib_debug_top_size[index]) { printf("%8x bytes (", lib_debug_top_size[index]); printsize(lib_debug_top_size[index]); printf(") allocated at %s:%d\n", lib_debug_top_filename[index], lib_debug_top_line[index]); } } #endif #endif }
void lib_debug_check(void) { #ifdef LIB_DEBUG unsigned int index, count; unsigned int leakbytes; #ifdef LIB_DEBUG_CALLER char **btstring; int btidx, spc; #endif count = 0; leakbytes = 0; lib_debug_leaklist_num = 0; for (index = 0; index < LIB_DEBUG_SIZE; index++) { if (lib_debug_address[index] != NULL) { count++; #ifdef LIB_DEBUG_PINPOINT lib_debug_leaklist_add(index); #else printf("Warning: Memory block allocated here was not free'd (Memory leak with size 0x%x at %p).", lib_debug_size[index], lib_debug_address[index]); printf("\n"); #endif leakbytes += lib_debug_size[index]; #if LIB_DEBUG_GUARD > 0 lib_debug_guard_remove((char *)lib_debug_address[index]); #endif } } #ifdef LIB_DEBUG_PINPOINT printf("\n"); for (index = 0; index < lib_debug_leaklist_num; index++) { printf("%s:%d: Warning: Memory block(s) allocated here was not free'd (Memory leak with size 0x%x at %p).", lib_debug_leaklist_filename[index], lib_debug_leaklist_line[index], lib_debug_leaklist_size[index], lib_debug_leaklist_address[index]); #ifdef LIB_DEBUG_CALLER printf("\ncallstack:\n"); btstring = backtrace_symbols(lib_debug_leaklist_bt_caller[index], lib_debug_leaklist_bt_numcaller[index]); if (btstring == NULL) { printf(" lookup failed\n"); } else { for (btidx = 1; btidx < lib_debug_leaklist_bt_numcaller[index]; btidx++) { printf(" "); for (spc = 0; spc < btidx; spc++) { printf(" "); } printf("%s\n", btstring[btidx]); } } free(btstring); #endif printf("\n"); } #endif printf("\nTotal memory leaks: %d", count); #ifdef LIB_DEBUG_PINPOINT printf(" in %d lines", lib_debug_leaklist_num); #endif printf(". Total bytes leaked: 0x%x (", leakbytes); printsize(leakbytes); printf(").\n\nmax. total memory that was allocated: 0x%x bytes. (", lib_debug_max_total); printsize(lib_debug_max_total); printf(")\n"); #ifdef LIB_DEBUG_PINPOINT printf("\nTop %d largest allocated blocks:\n", LIB_DEBUG_TOPMAX); for (index = 0; index < LIB_DEBUG_TOPMAX; index++) { if (lib_debug_top_size[index]) { printf("%8x bytes (", lib_debug_top_size[index]); printsize(lib_debug_top_size[index]); printf(") allocated at %s:%d\n", lib_debug_top_filename[index], lib_debug_top_line[index]); } } #endif #endif }