/** * Checks for memory leaks. * * @return zero if no leakage is found; the number of leaks otherwise */ int check_leaks() { int leak_cnt = 0; fast_mutex_autolock lock_ptr(new_ptr_lock); fast_mutex_autolock lock_output(new_output_lock); new_ptr_list_t* ptr = new_ptr_list.next; while (ptr != &new_ptr_list) { const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; if (ptr->magic != MAGIC) { fprintf(new_output_fp, "warning: heap data corrupt near %p\n", pointer); } #if _DEBUG_NEW_TAILCHECK if (!check_tail(ptr)) { fprintf(new_output_fp, "warning: overwritten past end of object at %p\n", pointer); } #endif fprintf(new_output_fp, "Leaked object at %p (size %lu, ", pointer, (unsigned long)ptr->size); if (ptr->line != 0) print_position(ptr->file, ptr->line); else print_position(ptr->addr, ptr->line); if( new_verbose_flag ) { fprintf(new_output_fp, "):\n"); dump_leak(pointer, ptr); } else { fprintf(new_output_fp, ")\n"); } ptr = ptr->next; ++leak_cnt; } if (new_verbose_flag || leak_cnt) fprintf(new_output_fp, "*** %d leaks found\n", leak_cnt); return leak_cnt; }
/** * Checks for heap corruption. * * @return zero if no problem is found; the number of found memory * corruptions otherwise */ int check_mem_corruption() { int corrupt_cnt = 0; fast_mutex_autolock lock_ptr(new_ptr_lock); fast_mutex_autolock lock_output(new_output_lock); fprintf(new_output_fp, "*** Checking for memory corruption: START\n"); for (new_ptr_list_t* ptr = new_ptr_list.next; ptr != &new_ptr_list; ptr = ptr->next) { const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; if (ptr->magic == MAGIC #if _DEBUG_NEW_TAILCHECK && check_tail(ptr) #endif ) continue; #if _DEBUG_NEW_TAILCHECK if (ptr->magic != MAGIC) { #endif fprintf(new_output_fp, "Heap data corrupt near %p (size %lu, ", pointer, (unsigned long)ptr->size); #if _DEBUG_NEW_TAILCHECK } else { fprintf(new_output_fp, "Overwritten past end of object at %p (size %lu, ", pointer, (unsigned long)ptr->size); } #endif if (ptr->line != 0) print_position(ptr->file, ptr->line); else print_position(ptr->addr, ptr->line); fprintf(new_output_fp, ")\n"); ++corrupt_cnt; } fprintf(new_output_fp, "*** Checking for memory corruption: %d FOUND\n", corrupt_cnt); return corrupt_cnt; }
/** * Checks for heap corruption. * * @return zero if no problem is found; the number of found memory * corruptions otherwise */ int check_mem_corruption() { int corrupt_cnt = 0; fast_mutex_autolock lock_ptr(new_ptr_lock); fast_mutex_autolock lock_output(new_output_lock); const char * msg_out_check_mem_start = "[QxOrm] **** Checking for memory corruption: START ****"; Q_UNUSED(msg_out_check_mem_start); qDebug("%s", msg_out_check_mem_start); for (new_ptr_list_t* ptr = new_ptr_list.next; ptr != &new_ptr_list; ptr = ptr->next) { const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; if (ptr->magic == MAGIC #if _DEBUG_NEW_TAILCHECK && check_tail(ptr) #endif ) continue; #if _DEBUG_NEW_TAILCHECK if (ptr->magic != MAGIC) { #endif const char * msg_out_file = "[QxOrm] Heap data corrupt near %p (size %u, %s:%d)"; Q_UNUSED(msg_out_file); const char * msg_out_no_file = "[QxOrm] Heap data corrupt near %p (size %u, <Unknown>)"; Q_UNUSED(msg_out_no_file); if (ptr->line != 0) { qDebug(msg_out_file, pointer, ptr->size, ptr->file, ptr->line); ++corrupt_cnt; } #if (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) else { qDebug(msg_out_no_file, pointer, ptr->size); ++corrupt_cnt; } #endif // (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) #if _DEBUG_NEW_TAILCHECK } else { const char * msg_out_file = "[QxOrm] Overwritten past end of object at %p (size %u, %s:%d)"; Q_UNUSED(msg_out_file); const char * msg_out_no_file = "[QxOrm] Overwritten past end of object at %p (size %u, <Unknown>)"; Q_UNUSED(msg_out_no_file); if (ptr->line != 0) { qDebug(msg_out_file, pointer, ptr->size, ptr->file, ptr->line); ++corrupt_cnt; } #if (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) else { qDebug(msg_out_no_file, pointer, ptr->size); ++corrupt_cnt; } #endif // (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) } #endif } const char * msg_out_check_mem_end = "[QxOrm] **** Checking for memory corruption: %d FOUND ****"; Q_UNUSED(msg_out_check_mem_end); qDebug(msg_out_check_mem_end, corrupt_cnt); return corrupt_cnt; }
/** * Checks for memory leaks. * * @return zero if no leakage is found; the number of leaks otherwise */ int check_leaks() { int leak_cnt = 0; fast_mutex_autolock lock_ptr(new_ptr_lock); fast_mutex_autolock lock_output(new_output_lock); new_ptr_list_t* ptr = new_ptr_list.next; while (ptr != &new_ptr_list) { const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; if (ptr->magic != MAGIC) { const char * msg_out = "[QxOrm] warning: heap data corrupt near %p"; Q_UNUSED(msg_out); qDebug(msg_out, pointer); } #if _DEBUG_NEW_TAILCHECK if (!check_tail(ptr)) { const char * msg_out = "[QxOrm] warning: overwritten past end of object at %p"; Q_UNUSED(msg_out); qDebug(msg_out, pointer); } #endif const char * msg_out_file = "[QxOrm] Leaked object at %p (size %u, %s:%d)"; Q_UNUSED(msg_out_file); const char * msg_out_no_file = "[QxOrm] Leaked object at %p (size %u, <Unknown>)"; Q_UNUSED(msg_out_no_file); if (ptr->line != 0) { qDebug(msg_out_file, pointer, ptr->size, ptr->file, ptr->line); ++leak_cnt; } #if (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) else { qDebug(msg_out_no_file, pointer, ptr->size); ++leak_cnt; } #endif // (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) ptr = ptr->next; } if (new_verbose_flag || leak_cnt) { const char * msg_out_leak_cnt = "[QxOrm] **** %d memory leaks found ****"; Q_UNUSED(msg_out_leak_cnt); qDebug(msg_out_leak_cnt, leak_cnt); } return leak_cnt; }