Show
Ignore:
Timestamp:
13/05/10 17:30:03 (2 years ago)
Author:
westram
Message:
  • This patch stuffs all memory leaks in ARBDB (as far as covered by unit-tests) for DEBUG and NDEBUG version!
  • ARBDB global data (aka 'gb_local')
    • track number of opened/closed DBs
    • GBK_install_SIGSEGV_handler only once in GB_init_gb()
    • when closing last DB -> call GB_exit_gb() freeing more memory (also called atexit, including assertion failing if a DB is still open)
    • added class ARBDB_memory_manager (just calls gbm_init_mem + gbm_flush_mem)
    • GB_exit_gb flushes ARBDB_memory_manager (if all blocks were freed by gbm_free_mem, everything will be flushed)
  • fixed a few more static buffer leaks
  • gb_make_entry - alloc correct blocksizes for GB_STRING and GB_LINK
  • fixed a hack in gb_read_bin_rek_V2
    • was increasing size of memory block to avoid illegal memory access in decompress (introduced in [1003]; may occur again)
    • due to mismatch in size between gbm_get_mem and gbm_free_mem memory was never flushed even if all blocks have been freed
  • fixed memleak in gb_read_bin_rek_V2
    • when loading mapfile, previously created 'gb_main' was not freed
  • added allocation logger to admalloc.cxx (inactive - use TRACE_ALLOCS to activate it)
    • traces all allocs/frees of ARBDB managed memory
    • detects wrong usage (double free, size and index mismatch) and shows were the block was allocated
    • added new backtrace functions helpful for debugging (store stack-backtraces and print them later)
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/ARBDB/adstring.cxx

    r6640 r6654  
    167167GB_ERROR GB_await_error() { 
    168168    if (GB_error_buffer) { 
    169         static char *err = 0; 
    170         reassign(err, GB_error_buffer); 
    171         return err; 
     169        static SmartMallocPtr(char) err; 
     170        err             = GB_error_buffer; 
     171        GB_error_buffer = NULL; 
     172        return &*err; 
    172173    } 
    173174    gb_assert(0);               // please correct error handling 
     
    11131114#define MAX_BACKTRACE 66 
    11141115 
    1115 void GBK_dump_backtrace(FILE *out, GB_ERROR error) { 
    1116     void   *array[MAX_BACKTRACE]; 
    1117     size_t  size = backtrace(array, MAX_BACKTRACE); // get void*'s for all entries on the stack 
    1118  
    1119     if (!out) out = stderr; 
    1120  
    1121     // print out all the frames to out 
    1122     fprintf(out, "\n-------------------- ARB-backtrace for '%s':\n", error); 
    1123     backtrace_symbols_fd(array, size, fileno(out)); 
    1124     if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out); 
    1125     fputs("-------------------- End of backtrace\n", out); 
    1126     fflush(out); 
     1116class BackTraceInfo { 
     1117    void   **array; 
     1118    size_t  size; 
     1119public: 
     1120    BackTraceInfo(size_t skipFramesAtBottom) { 
     1121        void *tmp[MAX_BACKTRACE]; 
     1122        size = backtrace(tmp, MAX_BACKTRACE); 
     1123 
     1124        size_t ssize = skipFramesAtBottom*sizeof(*array); 
     1125        size_t msize = size*sizeof(*array) - ssize; 
     1126 
     1127        gb_assert(msize>0); 
     1128         
     1129        array = (void**)malloc(msize); 
     1130        memcpy(array, tmp+skipFramesAtBottom, msize); 
     1131    } 
     1132    ~BackTraceInfo() { free(array); } 
     1133 
     1134    void dump(FILE *out, GB_CSTR message) { 
     1135        // print out all the frames to out 
     1136        fprintf(out, "\n-------------------- ARB-backtrace '%s':\n", message); 
     1137        backtrace_symbols_fd(array, size, fileno(out)); 
     1138        if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out); 
     1139        fputs("-------------------- End of backtrace\n", out); 
     1140        fflush(out); 
     1141    } 
     1142}; 
     1143 
     1144class BackTraceInfo *GBK_get_backtrace(size_t skipFramesAtBottom) { 
     1145    return new BackTraceInfo(skipFramesAtBottom); 
     1146} 
     1147void GBK_dump_former_backtrace(class BackTraceInfo *trace, FILE *out, GB_CSTR message) { 
     1148    trace->dump(out, message); 
     1149} 
     1150void GBK_free_backtrace(class BackTraceInfo *trace) { 
     1151    delete trace; 
     1152} 
     1153 
     1154void GBK_dump_backtrace(FILE *out, GB_CSTR message) { 
     1155    BackTraceInfo trace(0); 
     1156    trace.dump(out ? out : stderr, message); 
    11271157} 
    11281158