diff options
author | Andrei Karas <akaras@inbox.ru> | 2012-02-23 03:05:04 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2012-02-23 03:05:04 +0300 |
commit | fd5ee0e689e15ffc15e1bc70f33ca93915830346 (patch) | |
tree | cac1dc8e6bd1fe5ff7141e125f20cc298dd8026c | |
parent | 94a1361f88afaa757414d42bb59e5c663f3dbc7f (diff) | |
download | mv-fd5ee0e689e15ffc15e1bc70f33ca93915830346.tar.gz mv-fd5ee0e689e15ffc15e1bc70f33ca93915830346.tar.bz2 mv-fd5ee0e689e15ffc15e1bc70f33ca93915830346.tar.xz mv-fd5ee0e689e15ffc15e1bc70f33ca93915830346.zip |
Remove debug files.
It not usefull in normal usage, because need only for memory debug.
-rwxr-xr-x | configure.ac | 11 | ||||
-rw-r--r-- | src/Makefile.am | 13 | ||||
-rw-r--r-- | src/debug/debug_new.cpp | 879 | ||||
-rw-r--r-- | src/debug/debug_new.h | 183 | ||||
-rw-r--r-- | src/debug/fast_mutex.h | 314 | ||||
-rw-r--r-- | src/debug/static_assert.h | 53 |
6 files changed, 1 insertions, 1452 deletions
diff --git a/configure.ac b/configure.ac index de9b4bafb..42b07ab42 100755 --- a/configure.ac +++ b/configure.ac @@ -183,17 +183,6 @@ esac],[portable_enabled=false]) AM_CONDITIONAL(ENABLE_PORTABLE, test x$portable_enabled = xtrue) -# Enable debug -AC_ARG_ENABLE(memdebug, -[ --enable-memdebug Turn on memory debug mode], -[case "${enableval}" in - yes) memdebug_enabled=true ;; - no) memdebug_enabled=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-memdebug) ;; -esac],[memdebug_enabled=false]) - -AM_CONDITIONAL(ENABLE_MEM_DEBUG, test x$memdebug_enabled = xtrue) - # Enable unit tests AC_ARG_ENABLE(unittests, [ --enable-unittests Turn on unit tests], diff --git a/src/Makefile.am b/src/Makefile.am index aca581e22..d0723cc06 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,18 +10,7 @@ if ENABLE_PORTABLE manaplus_CXXFLAGS += -DENABLE_PORTABLE endif -if ENABLE_MEM_DEBUG -manaplus_CXXFLAGS += -DENABLE_MEM_DEBUG - -manaplus_SOURCES = debug/debug_new.cpp \ - debug/debug_new.h \ - debug/fast_mutex.h \ - debug/static_assert.h -else -manaplus_SOURCES = -endif - -manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ +manaplus_SOURCES = gui/widgets/avatarlistbox.cpp \ gui/widgets/avatarlistbox.h \ gui/widgets/battletab.cpp \ gui/widgets/battletab.h \ diff --git a/src/debug/debug_new.cpp b/src/debug/debug_new.cpp deleted file mode 100644 index fb83cab4a..000000000 --- a/src/debug/debug_new.cpp +++ /dev/null @@ -1,879 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - * original version changed for ManaPlus - * - * Copyright (C) 2011 ManaPlus developers - */ - -/** - * @file debug_new.cpp - * - * Implementation of debug versions of new and delete to check leakage. - * - * @version 4.14, 2008/10/20 - * @author Wu Yongwei - * - */ - -#ifdef ENABLE_MEM_DEBUG -#include <new> -#include <assert.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef __unix__ -#include <alloca.h> -#endif -#ifdef _WIN32 -#include <malloc.h> -#endif -#include "debug/fast_mutex.h" -#include "debug/static_assert.h" - -//define DUMP_MEM_ADDRESSES 1 - -#if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS) -#error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work" -#endif - -/** - * @def M_DEBUG_NEW_ALIGNMENT - * - * The alignment requirement of allocated memory blocks. It must be a - * power of two. - */ -#ifndef M_DEBUG_NEW_ALIGNMENT -#define M_DEBUG_NEW_ALIGNMENT 16 -#endif - -/** - * @def M_DEBUG_NEW_CALLER_ADDRESS - * - * The expression to return the caller address. #print_position will - * later on use this address to print the position information of memory - * operation points. - */ -#ifndef M_DEBUG_NEW_CALLER_ADDRESS -#ifdef __GNUC__ -#define M_DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0) -#else -#define M_DEBUG_NEW_CALLER_ADDRESS NULL -#endif -#endif - -/** - * @def M_DEBUG_NEW_ERROR_ACTION - * - * The action to take when an error occurs. The default behaviour is to - * call \e abort, unless \c M_DEBUG_NEW_ERROR_CRASH is defined, in which - * case a segmentation fault will be triggered instead (which can be - * useful on platforms like Windows that do not generate a core dump - * when \e abort is called). - */ -#ifndef M_DEBUG_NEW_ERROR_ACTION -#ifndef M_DEBUG_NEW_ERROR_CRASH -#define M_DEBUG_NEW_ERROR_ACTION abort() -#else -#define M_DEBUG_NEW_ERROR_ACTION do { *((char*)0) = 0; abort(); } while (0) -#endif -#endif - -/** - * @def M_DEBUG_NEW_FILENAME_LEN - * - * The length of file name stored if greater than zero. If it is zero, - * only a const char pointer will be stored. Currently the default - * behaviour is to copy the file name, because I found that the exit - * leakage check cannot access the address of the file name sometimes - * (in my case, a core dump will occur when trying to access the file - * name in a shared library after a \c SIGINT). The current default - * value makes the size of new_ptr_list_t 64 on 32-bit platforms. - */ -#ifndef M_DEBUG_NEW_FILENAME_LEN -#define M_DEBUG_NEW_FILENAME_LEN 100 -#endif - -/** - * @def M_DEBUG_NEW_PROGNAME - * - * The program (executable) name to be set at compile time. It is - * better to assign the full program path to #new_progname in \e main - * (at run time) than to use this (compile-time) macro, but this macro - * serves well as a quick hack. Note also that double quotation marks - * need to be used around the program name, i.e., one should specify a - * command-line option like <code>-DM_DEBUG_NEW_PROGNAME=\"a.out\"</code> - * in \e bash, or <code>-DM_DEBUG_NEW_PROGNAME=\"a.exe\"</code> in the - * Windows command prompt. - */ -#ifndef M_DEBUG_NEW_PROGNAME -#define M_DEBUG_NEW_PROGNAME NULL -#endif - -/** - * @def M_DEBUG_NEW_STD_OPER_NEW - * - * Macro to indicate whether the standard-conformant behaviour of - * <code>operator new</code> is wanted. It is on by default now, but - * the user may set it to \c 0 to revert to the old behaviour. - */ -#ifndef M_DEBUG_NEW_STD_OPER_NEW -#define M_DEBUG_NEW_STD_OPER_NEW 1 -#endif - -/** - * @def M_DEBUG_NEW_TAILCHECK - * - * Macro to indicate whether a writing-past-end check will be performed. - * Define it to a positive integer as the number of padding bytes at the - * end of a memory block for checking. - */ -#ifndef M_DEBUG_NEW_TAILCHECK -#define M_DEBUG_NEW_TAILCHECK 0 -#endif - -/** - * @def M_DEBUG_NEW_TAILCHECK_CHAR - * - * Value of the padding bytes at the end of a memory block. - */ -#ifndef M_DEBUG_NEW_TAILCHECK_CHAR -#define M_DEBUG_NEW_TAILCHECK_CHAR 0xCC -#endif - -/** - * @def M_DEBUG_NEW_USE_ADDR2LINE - * - * Whether to use \e addr2line to convert a caller address to file/line - * information. Defining it to a non-zero value will enable the - * conversion (automatically done if GCC is detected). Defining it to - * zero will disable the conversion. - */ -#ifndef M_DEBUG_NEW_USE_ADDR2LINE -#ifdef __GNUC__ -#define M_DEBUG_NEW_USE_ADDR2LINE 1 -#else -#define M_DEBUG_NEW_USE_ADDR2LINE 0 -#endif -#endif - -#ifdef _MSC_VER -#pragma warning(disable: 4073) // #pragma init_seg(lib) used -#pragma warning(disable: 4290) // C++ exception specification ignored -#pragma init_seg(lib) -#endif - -#undef M_DEBUG_NEW_EMULATE_MALLOC -#undef M_DEBUG_NEW_REDEFINE_NEW -/** - * Macro to indicate whether redefinition of \c new is wanted. Here it - * is defined to \c 0 to disable the redefinition of \c new. - */ -#define M_DEBUG_NEW_REDEFINE_NEW 0 -#include "debug_new.h" - -/** - * Gets the aligned value of memory block size. - */ -#define align(s) \ - (((s) + M_DEBUG_NEW_ALIGNMENT - 1) & ~(M_DEBUG_NEW_ALIGNMENT - 1)) - -/** - * Structure to store the position information where \c new occurs. - */ -struct new_ptr_list_t -{ - new_ptr_list_t* next; - new_ptr_list_t* prev; - size_t size; - union - { -#if M_DEBUG_NEW_FILENAME_LEN == 0 - const char* file; -#else - char file[M_DEBUG_NEW_FILENAME_LEN]; -#endif - void* addr; - }; - unsigned line :31; - unsigned is_array :1; - unsigned magic; - unsigned dumped; -}; - -/** - * Magic number for error detection. - */ -const unsigned MAGIC = 0x4442474E; - -/** - * The extra memory allocated by <code>operator new</code>. - */ -const int ALIGNED_LIST_ITEM_SIZE = align(sizeof(new_ptr_list_t)); - -/** - * List of all new'd pointers. - */ -static new_ptr_list_t new_ptr_list = -{ - &new_ptr_list, - &new_ptr_list, - 0, - { -#if M_DEBUG_NEW_FILENAME_LEN == 0 - NULL -#else - "" -#endif - }, - 0, - 0, - MAGIC, - false -}; - -/** - * The mutex guard to protect simultaneous access to the pointer list. - */ -static fast_mutex new_ptr_lock; - -/** - * The mutex guard to protect simultaneous output to #new_output_fp. - */ -static fast_mutex new_output_lock; - -/** - * Total memory allocated in bytes. - */ -static size_t total_mem_alloc = 0; - -/** - * Flag to control whether #check_leaks will be automatically called on - * program exit. - */ -bool new_autocheck_flag = true; - -/** - * Flag to control whether verbose messages are output. - */ -bool new_verbose_flag = false; - -/** - * Pointer to the output stream. The default output is \e stderr, and - * one may change it to a user stream if needed (say, #new_verbose_flag - * is \c true and there are a lot of (de)allocations). - */ -FILE* new_output_fp = stderr; - -/** - * Pointer to the program name. Its initial value is the macro - * #M_DEBUG_NEW_PROGNAME. You should try to assign the program path to - * it early in your application. Assigning <code>argv[0]</code> to it - * in \e main is one way. If you use \e bash or \e ksh (or similar), - * the following statement is probably what you want: - * `<code>new_progname = getenv("_");</code>'. - */ -const char* new_progname = M_DEBUG_NEW_PROGNAME; - -#if M_DEBUG_NEW_USE_ADDR2LINE -/** - * Tries printing the position information from an instruction address. - * This is the version that uses \e addr2line. - * - * @param addr the instruction address to convert and print - * @return \c true if the address is converted successfully (and - * the result is printed); \c false if no useful - * information is got (and nothing is printed) - */ -static bool print_position_from_addr(const void* addr) -{ - static const void* last_addr = NULL; - static char last_info[256] = ""; - if (addr == last_addr) - { - if (last_info[0] == '\0') - return false; - fprintf(new_output_fp, "%s", last_info); - return true; - } - if (new_progname) - { - const char addr2line_cmd[] = "addr2line -e "; -#if defined(__CYGWIN__) || defined(_WIN32) - const int exeext_len = 4; -#else - const int exeext_len = 0; -#endif -#if !defined(__CYGWIN__) && defined(__unix__) - const char ignore_err[] = " 2>/dev/null"; -#elif defined(__CYGWIN__) || \ - (defined(_WIN32) && defined(WINVER) && WINVER >= 0x0500) - const char ignore_err[] = " 2>nul"; -#else - const char ignore_err[] = ""; -#endif - char* cmd = (char*)alloca(strlen(new_progname) - + exeext_len - + sizeof addr2line_cmd - 1 - + sizeof ignore_err - 1 - + sizeof(void*) * 2 - + 4 /* SP + "0x" + null */); - strcpy(cmd, addr2line_cmd); - strcpy(cmd + sizeof addr2line_cmd - 1, new_progname); - size_t len = strlen(cmd); -#if defined(__CYGWIN__) || defined(_WIN32) - if (len <= 4 || (strcmp(cmd + len - 4, ".exe") != 0 - && strcmp(cmd + len - 4, ".EXE") != 0)) - { - strcpy(cmd + len, ".exe"); - len += 4; - } -#endif - sprintf(cmd + len, " %p%s", addr, ignore_err); - FILE* fp = popen(cmd, "r"); - if (fp) - { - char buffer[sizeof last_info] = ""; - len = 0; - if (fgets(buffer, sizeof buffer, fp)) - { - len = strlen(buffer); - if (buffer[len - 1] == '\n') - buffer[--len] = '\0'; - } - int res = pclose(fp); - // Display the file/line information only if the command - // is executed successfully and the output points to a - // valid position, but the result will be cached if only - // the command is executed successfully. - if (res == 0 && len > 0) - { - last_addr = addr; - if (buffer[len - 1] == '0' && buffer[len - 2] == ':') - last_info[0] = '\0'; - else - { - fprintf(new_output_fp, "%s", buffer); - strcpy(last_info, buffer); - return true; - } - } - } - } - return false; -} -#else -/** - * Tries printing the position information from an instruction address. - * This is the stub version that does nothing at all. - * - * @return \c false always - */ -static bool print_position_from_addr(const void*) -{ - return false; -} -#endif // M_DEBUG_NEW_USE_ADDR2LINE - -/** - * Prints the position information of a memory operation point. When \c - * M_DEBUG_NEW_USE_ADDR2LINE is defined to a non-zero value, this - * function will try to convert a given caller address to file/line - * information with \e addr2line. - * - * @param ptr source file name if \e line is non-zero; caller address - * otherwise - * @param line source line number if non-zero; indication that \e ptr - * is the caller address otherwise - */ -static void print_position(const void* ptr, int line) -{ - if (line != 0) // Is file/line information present? - { - fprintf(new_output_fp, "%s:%d", (const char*)ptr, line); - } - else if (ptr != NULL) // Is caller address present? - { - if (!print_position_from_addr(ptr)) // Fail to get source position? - fprintf(new_output_fp, "%p", ptr); - } - else // No information is present - { - fprintf(new_output_fp, "<Unknown>"); - } -} - -#if M_DEBUG_NEW_TAILCHECK -/** - * Checks whether the padding bytes at the end of a memory block is - * tampered with. - * - * @param ptr pointer to a new_ptr_list_t struct - * @return \c true if the padding bytes are untouched; \c false - * otherwise - */ -static bool check_tail(new_ptr_list_t* ptr) -{ - const unsigned char* const pointer = (unsigned char*)ptr + - ALIGNED_LIST_ITEM_SIZE + ptr->size; - for (int i = 0; i < M_DEBUG_NEW_TAILCHECK; ++i) - { - if (pointer[i] != M_DEBUG_NEW_TAILCHECK_CHAR) - return false; - } - return true; -} -#endif - -/** - * Allocates memory and initializes control data. - * - * @param size size of the required memory block - * @param file null-terminated string of the file name - * @param line line number - * @param is_array boolean value whether this is an array operation - * @return pointer to the user-requested memory area; \c NULL - * if memory allocation is not successful - */ -static void* alloc_mem(size_t size, const char* file, int line, bool is_array) -{ - assert(line >= 0); - STATIC_ASSERT((M_DEBUG_NEW_ALIGNMENT & (M_DEBUG_NEW_ALIGNMENT - 1)) == 0, - Alignment_must_be_power_of_two); - STATIC_ASSERT(M_DEBUG_NEW_TAILCHECK >= 0, Invalid_tail_check_length); - size_t s = size + ALIGNED_LIST_ITEM_SIZE + M_DEBUG_NEW_TAILCHECK; - new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s); - if (ptr == NULL) - { -#if M_DEBUG_NEW_STD_OPER_NEW - return NULL; -#else - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "Out of memory when allocating %u bytes\n", - size); - fflush(new_output_fp); - M_DEBUG_NEW_ERROR_ACTION; -#endif - } - void* pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; -#if M_DEBUG_NEW_FILENAME_LEN == 0 - ptr->file = file; -#else - if (line) - { - strncpy(ptr->file, file, M_DEBUG_NEW_FILENAME_LEN - 1) - [M_DEBUG_NEW_FILENAME_LEN - 1] = '\0'; - } - else - { - ptr->addr = (void*)file; - } -#endif - ptr->line = line; - ptr->is_array = is_array; - ptr->size = size; - ptr->magic = MAGIC; - { - fast_mutex_autolock lock(new_ptr_lock); - ptr->prev = new_ptr_list.prev; - ptr->next = &new_ptr_list; - new_ptr_list.prev->next = ptr; - new_ptr_list.prev = ptr; - } - ptr->dumped = 0; -#if M_DEBUG_NEW_TAILCHECK - memset((char*)pointer + size, M_DEBUG_NEW_TAILCHECK_CHAR, - M_DEBUG_NEW_TAILCHECK); -#endif - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "new%s: allocated %p (size %u, ", - is_array ? "[]" : "", - pointer, (unsigned)size); - if (line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, ")\n"); - } - total_mem_alloc += size; - return pointer; -} - -/** - * Frees memory and adjusts pointers. - * - * @param pointer pointer to delete - * @param addr pointer to the caller - * @param is_array flag indicating whether it is invoked by a - * <code>delete []</code> call - */ -static void free_pointer(void* pointer, void* addr, bool is_array) -{ - if (pointer == NULL) - return; - new_ptr_list_t* ptr = - (new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE); - if (ptr->magic != MAGIC) - { - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, "delete%s: invalid pointer %p (", - is_array ? "[]" : "", pointer); - print_position(addr, 0); - fprintf(new_output_fp, ")\n"); - } - check_mem_corruption(); - fflush(new_output_fp); - M_DEBUG_NEW_ERROR_ACTION; - } - if (is_array != ptr->is_array) - { - const char* msg; - if (is_array) - msg = "delete [] after new"; - else - msg = "delete after new []"; - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "%s: pointer %p (size %u)\n\tat ", - msg, - (char*)ptr + ALIGNED_LIST_ITEM_SIZE, - (unsigned)ptr->size); - print_position(addr, 0); - fprintf(new_output_fp, "\n\toriginally allocated at "); - if (ptr->line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, "\n"); - fflush(new_output_fp); - M_DEBUG_NEW_ERROR_ACTION; - } -#if M_DEBUG_NEW_TAILCHECK - if (!check_tail(ptr)) - { - check_mem_corruption(); - fflush(new_output_fp); - M_DEBUG_NEW_ERROR_ACTION; - } -#endif - { - fast_mutex_autolock lock(new_ptr_lock); - total_mem_alloc -= ptr->size; - ptr->magic = 0; - ptr->prev->next = ptr->next; - ptr->next->prev = ptr->prev; - } - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "delete%s: freed %p (size %u, %u bytes still allocated)\n", - is_array ? "[]" : "", - (char*)ptr + ALIGNED_LIST_ITEM_SIZE, - (unsigned)ptr->size, (unsigned)total_mem_alloc); - } - free(ptr); - return; -} - -/** - * Checks for memory leaks. - * - * @return zero if no leakage is found; the number of leaks otherwise - */ -int check_leaks() -{ - int leak_cnt = 0; - int dumped_cnt = 0; - int new_cnt = 0; - unsigned long new_size = 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; - fprintf(new_output_fp, "---LEAKS LIST---\n"); - - 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 M_DEBUG_NEW_TAILCHECK - if (!check_tail(ptr)) - { - fprintf(new_output_fp, - "warning: overwritten past end of object at %p\n", - pointer); - } -#endif -#ifndef DUMP_MEM_ADDRESSES - if (ptr->line != 0) -#endif - { - fprintf(new_output_fp, - "Leaked object at %p (size %u, dump %u, ", - pointer, (unsigned)ptr->size, ptr->dumped); - if (ptr->line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, ")\n"); - ++ new_cnt; - new_size += (unsigned long)ptr->size; - } - if (ptr->dumped) - ++ dumped_cnt; - - ++ ptr->dumped; - ptr = ptr->next; - ++ leak_cnt; - } - if (new_verbose_flag || leak_cnt) - { - fprintf(new_output_fp, "*** %d leaks found, new %d " - "(size %lu), dumped count %d\n", leak_cnt, new_cnt, - new_size, dumped_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 M_DEBUG_NEW_TAILCHECK - && check_tail(ptr) -#endif - ) - { - continue; - } -#if M_DEBUG_NEW_TAILCHECK - if (ptr->magic != MAGIC) - { -#endif - fprintf(new_output_fp, - "Heap data corrupt near %p (size %u, ", - pointer, - (unsigned)ptr->size); -#if M_DEBUG_NEW_TAILCHECK - } - else - { - fprintf(new_output_fp, - "Overwritten past end of object at %p (size %u, ", - pointer, - 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; -} - -void __debug_new_recorder::_M_process(void* pointer) -{ - if (pointer == NULL) - return; - new_ptr_list_t* ptr = - (new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE); - if (ptr->magic != MAGIC || ptr->line != 0) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "warning: debug_new used with placement new (%s:%d)\n", - _M_file, _M_line); - return; - } -#if M_DEBUG_NEW_FILENAME_LEN == 0 - ptr->file = _M_file; -#else - strncpy(ptr->file, _M_file, M_DEBUG_NEW_FILENAME_LEN - 1) - [M_DEBUG_NEW_FILENAME_LEN - 1] = '\0'; -#endif - ptr->line = _M_line; -} - -void* operator new (size_t size, const char* file, int line) -{ - void* ptr = alloc_mem(size, file, line, false); -#if M_DEBUG_NEW_STD_OPER_NEW - if (ptr) - return ptr; - else - throw std::bad_alloc(); -#else - return ptr; -#endif -} - -void* operator new [](size_t size, const char* file, int line) -{ - void* ptr = alloc_mem(size, file, line, true); -#if M_DEBUG_NEW_STD_OPER_NEW - if (ptr) - return ptr; - else - throw std::bad_alloc(); -#else - return ptr; -#endif -} - -void* operator new (size_t size) throw(std::bad_alloc) -{ - return operator new (size, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -void* operator new [](size_t size) throw(std::bad_alloc) -{ - return operator new [](size, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -#if !defined(__BORLANDC__) || __BORLANDC__ > 0x551 -void* operator new (size_t size, const std::nothrow_t&) throw() -{ - return alloc_mem(size, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0, false); -} - -void* operator new [](size_t size, const std::nothrow_t&) throw() -{ - return alloc_mem(size, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0, true); -} -#endif - -void operator delete (void* pointer) throw() -{ - free_pointer(pointer, M_DEBUG_NEW_CALLER_ADDRESS, false); -} - -void operator delete [](void* pointer) throw() -{ - free_pointer(pointer, M_DEBUG_NEW_CALLER_ADDRESS, true); -} - -#if HAVE_PLACEMENT_DELETE -void operator delete (void* pointer, const char* file, int line) throw() -{ - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "info: exception thrown on initializing object at %p (", - pointer); - print_position(file, line); - fprintf(new_output_fp, ")\n"); - } - operator delete (pointer); -} - -void operator delete [](void* pointer, const char* file, int line) throw() -{ - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "info: exception thrown on initializing objects at %p (", - pointer); - print_position(file, line); - fprintf(new_output_fp, ")\n"); - } - operator delete [](pointer); -} - -void operator delete (void* pointer, const std::nothrow_t&) throw() -{ - operator delete (pointer, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -void operator delete [](void* pointer, const std::nothrow_t&) throw() -{ - operator delete [](pointer, (char*)M_DEBUG_NEW_CALLER_ADDRESS, 0); -} -#endif // HAVE_PLACEMENT_DELETE - -int __debug_new_counter::_S_count = 0; - -/** - * Constructor to increment the count. - */ -__debug_new_counter::__debug_new_counter() -{ - ++_S_count; -} - -/** - * Destructor to decrement the count. When the count is zero, - * #check_leaks will be called. - */ -__debug_new_counter::~__debug_new_counter() -{ - if (--_S_count == 0 && new_autocheck_flag) - if (check_leaks()) - { - new_verbose_flag = true; -#if defined(__GNUC__) && __GNUC__ >= 3 - if (!getenv("GLIBCPP_FORCE_NEW") && !getenv("GLIBCXX_FORCE_NEW")) - fprintf(new_output_fp, -"*** WARNING: GCC 3 or later is detected, please make sure the\n" -" environment variable GLIBCPP_FORCE_NEW (GCC 3.2 and 3.3) or\n" -" GLIBCXX_FORCE_NEW (GCC 3.4 and later) is defined. Check the\n" -" README file for details.\n"); -#endif - } -} - -#endif diff --git a/src/debug/debug_new.h b/src/debug/debug_new.h deleted file mode 100644 index 157f2648a..000000000 --- a/src/debug/debug_new.h +++ /dev/null @@ -1,183 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - * original version changed for ManaPlus - * - * Copyright (C) 2011 ManaPlus developers - */ - -/** - * @file debug_new.h - * - * Header file for checking leaks caused by unmatched new/delete. - * - * @version 4.4, 2007/12/31 - * @author Wu Yongwei - * - */ - -#ifndef M_DEBUG_NEW_H -#define M_DEBUG_NEW_H - -#include <new> -#include <stdio.h> - -/** - * @def HAVE_PLACEMENT_DELETE - * - * Macro to indicate whether placement delete operators are supported on - * a certain compiler. Some compilers, like Borland C++ Compiler 5.5.1 - * and Digital Mars Compiler 8.42, do not support them, and the user - * must define this macro to \c 0 to make the program compile. Also - * note that in that case memory leakage will occur if an exception is - * thrown in the initialization (constructor) of a dynamically created - * object. - */ -#ifndef HAVE_PLACEMENT_DELETE -#define HAVE_PLACEMENT_DELETE 1 -#endif - -/** - * @def M_DEBUG_NEW_REDEFINE_NEW - * - * Macro to indicate whether redefinition of \c new is wanted. If one - * wants to define one's own <code>operator new</code>, to call - * <code>operator new</code> directly, or to call placement \c new, it - * should be defined to \c 0 to alter the default behaviour. Unless, of - * course, one is willing to take the trouble to write something like: - * @code - * # ifdef new - * # define _NEW_REDEFINED - * # undef new - * # endif - * - * // Code that uses new is here - * - * # ifdef _NEW_REDEFINED - * # ifdef DEBUG_NEW - * # define new DEBUG_NEW - * # endif - * # undef _NEW_REDEFINED - * # endif - * @endcode - */ -#ifndef M_DEBUG_NEW_REDEFINE_NEW -#define M_DEBUG_NEW_REDEFINE_NEW 1 -#endif - -/* Prototypes */ -int check_leaks(); -int check_mem_corruption(); -void* operator new(size_t size, const char* file, int line); -void* operator new[](size_t size, const char* file, int line); -#if HAVE_PLACEMENT_DELETE -void operator delete(void* pointer, const char* file, int line) throw(); -void operator delete[](void* pointer, const char* file, int line) throw(); -#endif -#if defined(_MSC_VER) && _MSC_VER < 1300 -// MSVC 6 requires the following declarations; or the non-placement -// new[]/delete[] will not compile. -void* operator new[](size_t) throw(std::bad_alloc); -void operator delete[](void*) throw(); -#endif - -/* Control variables */ -extern bool new_autocheck_flag; // default to true: call check_leaks() on exit -extern bool new_verbose_flag; // default to false: no verbose information -extern FILE* new_output_fp; // default to stderr: output to console -extern const char* new_progname; // default to NULL; should be assigned argv[0] - -/** - * @def DEBUG_NEW - * - * Macro to catch file/line information on allocation. If - * #M_DEBUG_NEW_REDEFINE_NEW is \c 0, one can use this macro directly; - * otherwise \c new will be defined to it, and one must use \c new - * instead. - */ -#define DEBUG_NEW __debug_new_recorder(__FILE__, __LINE__) ->* new - -# if M_DEBUG_NEW_REDEFINE_NEW -# define new DEBUG_NEW -# endif -# ifdef M_DEBUG_NEW_EMULATE_MALLOC -# include <stdlib.h> -# ifdef new -# define malloc(s) ((void*)(new char[s])) -# else -# define malloc(s) ((void*)(DEBUG_NEW char[s])) -# endif -# define free(p) delete[] (char*)(p) -# define default_free free -# endif - -/** - * Recorder class to remember the call context. - * - * The idea comes from <a href="http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/7089382e3bc1c489/85f9107a1dc79ee9?#85f9107a1dc79ee9">Greg Herlihy's post</a> in comp.lang.c++.moderated. - */ -class __debug_new_recorder -{ - const char* _M_file; - const int _M_line; - void _M_process(void* pointer); -public: - /** - * Constructor to remember the call context. The information will - * be used in __debug_new_recorder::operator->*. - */ - __debug_new_recorder(const char* file, int line) - : _M_file(file), _M_line(line) {} - /** - * Operator to write the context information to memory. - * <code>operator->*</code> is chosen because it has the right - * precedence, it is rarely used, and it looks good: so people can - * tell the special usage more quickly. - */ - template <class _Tp> _Tp* operator->*(_Tp* pointer) - { _M_process(pointer); return pointer; } -private: - __debug_new_recorder(const __debug_new_recorder&); - __debug_new_recorder& operator=(const __debug_new_recorder&); -}; - -/** - * Counter class for on-exit leakage check. - * - * This technique is learnt from <em>The C++ Programming Language</em> by - * Bjarne Stroustup. - */ -class __debug_new_counter -{ - static int _S_count; -public: - __debug_new_counter(); - ~__debug_new_counter(); -}; -/** Counting object for each file including debug_new.h. */ -static __debug_new_counter __debug_new_count; - -#endif // M_DEBUG_NEW_H diff --git a/src/debug/fast_mutex.h b/src/debug/fast_mutex.h deleted file mode 100644 index 60ad1f305..000000000 --- a/src/debug/fast_mutex.h +++ /dev/null @@ -1,314 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - * original version changed for ManaPlus - * - * Copyright (C) 2011 ManaPlus developers - */ - -/** - * @file fast_mutex.h - * - * A fast mutex implementation for POSIX and Win32. - * - * @version 1.18, 2005/05/06 - * @author Wu Yongwei - * - */ - -#ifndef M_FAST_MUTEX_H -#define M_FAST_MUTEX_H - -# if !defined(_NOTHREADS) -# if !defined(_WIN32THREADS) && \ - (defined(_WIN32) && defined(_MT)) -// Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC, -// or -mthreads in MinGW GCC. -# define _WIN32THREADS -# elif !defined(_PTHREADS) && \ - defined(_REENTRANT) -// Automatically use _PTHREADS when specifying -pthread in GCC. -// N.B. I do not detect on _PTHREAD_H since libstdc++-v3 under -// Linux will silently include <pthread.h> anyway. -# define _PTHREADS -# endif -# endif - -# if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS) -# define _NOTHREADS -# endif - -# if defined(_NOTHREADS) -# if defined(_PTHREADS) || defined(_WIN32THREADS) -# undef _NOTHREADS -# error "Cannot define multi-threaded mode with -D_NOTHREADS" -# if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT) -# error "Be sure to specify -mthreads with -D_WIN32THREADS" -# endif -# endif -# endif - -# ifndef _FAST_MUTEX_CHECK_INITIALIZATION -/** - * Macro to control whether to check for initialization status for each - * lock/unlock operation. Defining it to a non-zero value will enable - * the check, so that the construction/destruction of a static object - * using a static fast_mutex not yet constructed or already destroyed - * will work (with lock/unlock operations ignored). Defining it to zero - * will disable to check. - */ -# define _FAST_MUTEX_CHECK_INITIALIZATION 1 -# endif - -# if defined(_PTHREADS) && defined(_WIN32THREADS) -// Some C++ libraries have _PTHREADS defined even on Win32 platforms. -// Thus this hack. -# undef _PTHREADS -# endif - -# ifdef _DEBUG -# include <stdio.h> -# include <stdlib.h> -/** Macro for fast_mutex assertions. Real version (for debug mode). */ -# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ - if (!(_Expr)) { \ - fprintf(stderr, "fast_mutex::%s\n", _Msg); \ - abort(); \ - } -# else -/** Macro for fast_mutex assertions. Fake version (for release mode). */ -# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ - ((void)0) -# endif - -# ifdef _PTHREADS -# include <pthread.h> -/** - * Macro alias to `volatile' semantics. Here it is truly volatile since - * it is in a multi-threaded (POSIX threads) environment. - */ -# define __VOLATILE volatile - /** - * Class for non-reentrant fast mutexes. This is the implementation - * for POSIX threads. - */ - class fast_mutex - { - pthread_mutex_t _M_mtx_impl; -# if _FAST_MUTEX_CHECK_INITIALIZATION - bool _M_initialized; -# endif -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - ::pthread_mutex_init(&_M_mtx_impl, NULL); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = true; -# endif - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = false; -# endif - ::pthread_mutex_destroy(&_M_mtx_impl); - } - void lock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif - ::pthread_mutex_lock(&_M_mtx_impl); -# ifdef _DEBUG - // The following assertion should _always_ be true for a - // real `fast' pthread_mutex. However, this assertion can - // help sometimes, when people forget to use `-lpthread' and - // glibc provides an empty implementation. Having this - // assertion is also more consistent. - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - ::pthread_mutex_unlock(&_M_mtx_impl); - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -# endif // _PTHREADS - -# ifdef _WIN32THREADS -# include <windows.h> -/** - * Macro alias to `volatile' semantics. Here it is truly volatile since - * it is in a multi-threaded (Win32 threads) environment. - */ -# define __VOLATILE volatile - /** - * Class for non-reentrant fast mutexes. This is the implementation - * for Win32 threads. - */ - class fast_mutex - { - CRITICAL_SECTION _M_mtx_impl; -# if _FAST_MUTEX_CHECK_INITIALIZATION - bool _M_initialized; -# endif -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - ::InitializeCriticalSection(&_M_mtx_impl); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = true; -# endif - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = false; -# endif - ::DeleteCriticalSection(&_M_mtx_impl); - } - void lock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif - ::EnterCriticalSection(&_M_mtx_impl); -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - ::LeaveCriticalSection(&_M_mtx_impl); - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -# endif // _WIN32THREADS - -# ifdef _NOTHREADS -/** - * Macro alias to `volatile' semantics. Here it is not truly volatile - * since it is in a single-threaded environment. - */ -# define __VOLATILE - /** - * Class for non-reentrant fast mutexes. This is the null - * implementation for single-threaded environments. - */ - class fast_mutex - { -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); - } - void lock() - { -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -# endif // _NOTHREADS - -/** An acquistion-on-initialization lock class based on fast_mutex. */ -class fast_mutex_autolock -{ - fast_mutex& _M_mtx; -public: - explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx) - { - _M_mtx.lock(); - } - ~fast_mutex_autolock() - { - _M_mtx.unlock(); - } -private: - fast_mutex_autolock(const fast_mutex_autolock&); - fast_mutex_autolock& operator=(const fast_mutex_autolock&); -}; - -#endif // M_FAST_MUTEX_H diff --git a/src/debug/static_assert.h b/src/debug/static_assert.h deleted file mode 100644 index 17be7a5f3..000000000 --- a/src/debug/static_assert.h +++ /dev/null @@ -1,53 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - * original version changed for ManaPlus - * - * Copyright (C) 2011 ManaPlus developers - */ - -/** - * @file static_assert.h - * - * Template class to check validity duing compile time (adapted from Loki). - * - * @version 1.2, 2005/11/22 - * @author Wu Yongwei - * - */ - -#ifndef STATIC_ASSERT - -template <bool> struct __nvwa_compile_time_error; -template <> struct __nvwa_compile_time_error<true> {}; - -#define STATIC_ASSERT(_Expr, _Msg) \ - { \ - __nvwa_compile_time_error<((_Expr) != 0)> ERROR_##_Msg; \ - (void)ERROR_##_Msg; \ - } - -#endif // STATIC_ASSERT |