ManaPlus
|
#include "localconsts.h"
#include <new>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug/nvwa/_nvwa.h"
#include "debug/nvwa/c++11.h"
#include "debug/nvwa/fast_mutex.h"
#include "debug/nvwa/static_assert.h"
#include "debug/nvwa/debug_new.h"
Go to the source code of this file.
Data Structures | |
struct | new_ptr_list_t |
Macros | |
#define | _DEBUG_NEW_REDEFINE_NEW 0 |
#define | _DEBUG_NEW_ALIGNMENT 16 |
#define | _DEBUG_NEW_CALLER_ADDRESS _NULLPTR |
#define | _DEBUG_NEW_ERROR_ACTION abort() |
#define | _DEBUG_NEW_FILENAME_LEN 44 |
#define | _DEBUG_NEW_PROGNAME _NULLPTR |
#define | _DEBUG_NEW_REMEMBER_STACK_TRACE 0 |
#define | _DEBUG_NEW_STD_OPER_NEW 1 |
#define | _DEBUG_NEW_TAILCHECK 0 |
#define | _DEBUG_NEW_USE_ADDR2LINE 0 |
#define | ALIGN(s) (((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1)) |
Functions | |
static bool | print_position_from_addr (const void *) |
static void | print_position (const void *ptr, int line) |
static bool | is_leak_whitelisted (new_ptr_list_t *ptr) |
static void * | alloc_mem (size_t size, const char *file, int line, bool is_array) |
static void | free_pointer (void *usr_ptr, void *addr, bool is_array) |
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) |
void * | operator new (size_t size) |
void * | operator new[] (size_t size) |
void * | operator new (size_t size, const std::nothrow_t &) throw () |
void * | operator new[] (size_t size, const std::nothrow_t &) throw () |
void | operator delete (void *ptr) throw () |
void | operator delete[] (void *ptr) throw () |
void | operator delete (void *ptr, const char *file, int line) throw () |
void | operator delete[] (void *ptr, const char *file, int line) throw () |
void | operator delete (void *ptr, const std::nothrow_t &) throw () |
void | operator delete[] (void *ptr, const std::nothrow_t &) throw () |
Variables | |
static const unsigned | DEBUG_NEW_MAGIC = 0x4442474E |
static const int | ALIGNED_LIST_ITEM_SIZE = ((( sizeof(new_ptr_list_t) ) + 16 - 1) & ~( 16 - 1)) |
static new_ptr_list_t | new_ptr_list |
static fast_mutex | new_ptr_lock |
static fast_mutex | new_output_lock |
static size_t | total_mem_alloc = 0 |
bool | new_autocheck_flag = true |
bool | new_verbose_flag = false |
FILE * | new_output_fp = stderr |
const char * | new_progname = ((void *)0) |
stacktrace_print_callback_t | stacktrace_print_callback = ((void *)0) |
leak_whitelist_callback_t | leak_whitelist_callback = ((void *)0) |
Implementation of debug versions of new and delete to check leakage.
Definition in file debug_new.cpp.
#define _DEBUG_NEW_ALIGNMENT 16 |
#define _DEBUG_NEW_CALLER_ADDRESS _NULLPTR |
The expression to return the caller address. nvwa::print_position will later on use this address to print the position information of memory operation points.
#define _DEBUG_NEW_ERROR_ACTION abort() |
The action to take when an error occurs. The default behaviour is to call abort, unless _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 abort is called).
#define _DEBUG_NEW_FILENAME_LEN 44 |
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 value is non-zero (thus to copy the file name) on non-Windows platforms, because I once found that the exit leakage check could not access the address of the file name on Linux (in my case, a core dump occurred when check_leaks tried to access the file name in a shared library after a SIGINT
). This value makes the size of new_ptr_list_t 64
on non-Windows 32-bit platforms (w/o stack backtrace).
#define _DEBUG_NEW_PROGNAME _NULLPTR |
The program (executable) name to be set at compile time. It is better to assign the full program path to nvwa::new_progname in 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 -D_DEBUG_NEW_PROGNAME=\"a.out\"
in bash, or -D_DEBUG_NEW_PROGNAME=\"a.exe\"
in the Windows command prompt.
#define _DEBUG_NEW_REDEFINE_NEW 0 |
#define _DEBUG_NEW_REMEMBER_STACK_TRACE 0 |
Macro to indicate whether stack traces of allocations should be included in NVWA allocation information and be printed while leaks are reported. Useful to pinpoint leaks caused by strdup and other custom allocation functions. It is also very helpful in filtering out false positives caused by internal STL/C runtime operations. It is off by default because it is quite memory heavy. Set it to 1
to make all allocations have stack trace attached, or set to 2
to make only allocations that lack calling source code information (file and line) have the stack trace attached.
#define _DEBUG_NEW_STD_OPER_NEW 1 |
Macro to indicate whether the standard-conformant behaviour of operator new
is wanted. It is on by default now, but the user may set it to 0
to revert to the old behaviour.
#define _DEBUG_NEW_TAILCHECK 0 |
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.
#define _DEBUG_NEW_USE_ADDR2LINE 0 |
Whether to use 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.
#define ALIGN | ( | s | ) | (((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1)) |
|
static |
Allocates memory and initializes control data.
size | size of the required memory block |
file | null-terminated string of the file name |
line | line number |
is_array | boolean value whether this is an array operation |
Definition at line 587 of file debug_new.cpp.
References _DEBUG_NEW_ALIGNMENT, _DEBUG_NEW_ERROR_ACTION, _DEBUG_NEW_FILENAME_LEN, _DEBUG_NEW_TAILCHECK, _NULLPTR, new_ptr_list_t::addr, ALIGNED_LIST_ITEM_SIZE, DEBUG_NEW_MAGIC, new_ptr_list_t::file, new_ptr_list_t::is_array, new_ptr_list_t::line, new_ptr_list_t::magic, new_output_fp, new_output_lock, new_ptr_list, new_ptr_lock, new_verbose_flag, new_ptr_list_t::next, new_ptr_list_t::prev, print_position(), new_ptr_list_t::size, EmoteDB::size(), STATIC_ASSERT, and total_mem_alloc.
Referenced by operator new(), and operator new[]().
int check_leaks | ( | ) |
Checks for memory leaks.
Definition at line 769 of file debug_new.cpp.
References _NULLPTR, new_ptr_list_t::addr, ALIGNED_LIST_ITEM_SIZE, DEBUG_NEW_MAGIC, new_ptr_list_t::file, is_leak_whitelisted(), new_ptr_list_t::line, new_ptr_list_t::magic, new_output_fp, new_output_lock, new_ptr_list, new_ptr_lock, new_verbose_flag, new_ptr_list_t::next, print_position(), and new_ptr_list_t::size.
Referenced by debug_new_counter::~debug_new_counter().
int check_mem_corruption | ( | ) |
Checks for heap corruption.
Definition at line 844 of file debug_new.cpp.
References _DEBUG_NEW_TAILCHECK, _NULLPTR, new_ptr_list_t::addr, ALIGNED_LIST_ITEM_SIZE, DEBUG_NEW_MAGIC, new_ptr_list_t::file, new_ptr_list_t::line, new_ptr_list_t::magic, new_output_fp, new_output_lock, new_ptr_list, new_ptr_lock, new_ptr_list_t::next, print_position(), and new_ptr_list_t::size.
Referenced by free_pointer().
|
static |
Frees memory and adjusts pointers.
usr_ptr | pointer to the previously allocated memory |
addr | pointer to the caller |
is_array | flag indicating whether it is invoked by a delete[] call |
Definition at line 691 of file debug_new.cpp.
References _DEBUG_NEW_ERROR_ACTION, _NULLPTR, new_ptr_list_t::addr, ALIGNED_LIST_ITEM_SIZE, check_mem_corruption(), DEBUG_NEW_MAGIC, new_ptr_list_t::file, new_ptr_list_t::is_array, new_ptr_list_t::line, new_ptr_list_t::magic, Actions::msg(), new_output_fp, new_output_lock, new_ptr_lock, new_verbose_flag, new_ptr_list_t::next, new_ptr_list_t::prev, print_position(), new_ptr_list_t::size, and total_mem_alloc.
Referenced by operator delete(), and operator delete[]().
|
static |
Checks whether a leak should be ignored. Its runtime performance depends on the callback nvwa::leak_whitelist_callback.
ptr | pointer to a new_ptr_list_t struct |
true
if the leak should be whitelisted; false
otherwise Definition at line 540 of file debug_new.cpp.
References _NULLPTR, new_ptr_list_t::addr, new_ptr_list_t::file, leak_whitelist_callback, and new_ptr_list_t::line.
Referenced by check_leaks().
void operator delete | ( | void * | ptr | ) | |
throw | ( | ||||
) |
Deallocates memory.
ptr | pointer to the previously allocated memory |
Definition at line 1094 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, and free_pointer().
void operator delete | ( | void * | ptr, |
const char * | file, | ||
int | line | ||
) | |||
throw | ( | ||
) |
Placement deallocation function. For details, please check Section 5.3.4 of the C++ 1998 or 2011 Standard.
ptr | pointer to the previously allocated memory |
file | null-terminated string of the file name |
line | line number |
Definition at line 1134 of file debug_new.cpp.
References new_output_fp, new_output_lock, new_verbose_flag, and print_position().
void operator delete | ( | void * | ptr, |
const std::nothrow_t & | |||
) | |||
throw | ( | ||
) |
Placement deallocation function. For details, please check Section 5.3.4 of the C++ 1998 or 2011 Standard.
ptr | pointer to the previously allocated memory |
Definition at line 1176 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS.
void operator delete[] | ( | void * | ptr | ) | |
throw | ( | ||||
) |
Deallocates array memory.
ptr | pointer to the previously allocated memory |
Definition at line 1104 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, and free_pointer().
void operator delete[] | ( | void * | ptr, |
const char * | file, | ||
int | line | ||
) | |||
throw | ( | ||
) |
Placement deallocation function. For details, please check Section 5.3.4 of the C++ 1998 or 2011 Standard.
ptr | pointer to the previously allocated memory |
file | null-terminated string of the file name |
line | line number |
Definition at line 1156 of file debug_new.cpp.
References new_output_fp, new_output_lock, new_verbose_flag, and print_position().
void operator delete[] | ( | void * | ptr, |
const std::nothrow_t & | |||
) | |||
throw | ( | ||
) |
Placement deallocation function. For details, please check Section 5.3.4 of the C++ 1998 or 2011 Standard.
ptr | pointer to the previously allocated memory |
Definition at line 1187 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS.
void* operator new | ( | size_t | size | ) |
Allocates memory without file/line information.
size | size of the required memory block |
bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
Definition at line 1047 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, and EmoteDB::size().
void* operator new | ( | size_t | size, |
const char * | file, | ||
int | line | ||
) |
Allocates memory with file/line information.
size | size of the required memory block |
file | null-terminated string of the file name |
line | line number |
bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
Definition at line 1003 of file debug_new.cpp.
References alloc_mem(), and EmoteDB::size().
void* operator new | ( | size_t | size, |
const std::nothrow_t & | |||
) | |||
throw | ( | ||
) |
Allocates memory with no-throw guarantee.
size | size of the required memory block |
Definition at line 1072 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, alloc_mem(), and EmoteDB::size().
void* operator new[] | ( | size_t | size | ) |
Allocates array memory without file/line information.
size | size of the required memory block |
bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
Definition at line 1060 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, and EmoteDB::size().
void* operator new[] | ( | size_t | size, |
const char * | file, | ||
int | line | ||
) |
Allocates array memory with file/line information.
size | size of the required memory block |
file | null-terminated string of the file name |
line | line number |
bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
Definition at line 1026 of file debug_new.cpp.
References alloc_mem(), and EmoteDB::size().
void* operator new[] | ( | size_t | size, |
const std::nothrow_t & | |||
) | |||
throw | ( | ||
) |
Allocates array memory with no-throw guarantee.
size | size of the required memory block |
Definition at line 1084 of file debug_new.cpp.
References _DEBUG_NEW_CALLER_ADDRESS, alloc_mem(), and EmoteDB::size().
|
static |
Prints the position information of a memory operation point. When _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 addr2line.
ptr | source file name if line is non-zero; caller address otherwise |
line | source line number if non-zero; indication that ptr is the caller address otherwise |
Definition at line 488 of file debug_new.cpp.
References _NULLPTR, new_output_fp, and print_position_from_addr().
Referenced by alloc_mem(), check_leaks(), check_mem_corruption(), free_pointer(), operator delete(), and operator delete[]().
|
static |
Tries printing the position information from an instruction address. This is the stub version that does nothing at all.
false
always Definition at line 471 of file debug_new.cpp.
Referenced by print_position().
|
static |
The extra memory allocated by operator new
.
Definition at line 290 of file debug_new.cpp.
Referenced by debug_new_recorder::_M_process(), alloc_mem(), check_leaks(), check_mem_corruption(), and free_pointer().
|
static |
Definition of the constant magic number used for error detection.
Definition at line 285 of file debug_new.cpp.
Referenced by debug_new_recorder::_M_process(), alloc_mem(), check_leaks(), check_mem_corruption(), and free_pointer().
leak_whitelist_callback_t leak_whitelist_callback = ((void *)0) |
Pointer to the callback used to filter out false positives from leak reports. A null value means the lack of filtering.
Definition at line 368 of file debug_new.cpp.
Referenced by is_leak_whitelisted().
bool new_autocheck_flag = true |
Flag to control whether nvwa::check_leaks will be automatically called on program exit.
Definition at line 333 of file debug_new.cpp.
Referenced by debug_new_counter::~debug_new_counter().
FILE* new_output_fp = stderr |
Pointer to the output stream. The default output is stderr, and one may change it to a user stream if needed (say, new_verbose_flag is true
and there are a lot of (de)allocations).
Definition at line 345 of file debug_new.cpp.
Referenced by debug_new_recorder::_M_process(), alloc_mem(), check_leaks(), check_mem_corruption(), free_pointer(), operator delete(), operator delete[](), print_position(), and debug_new_counter::~debug_new_counter().
|
static |
The mutex guard to protect simultaneous output to new_output_fp.
Definition at line 322 of file debug_new.cpp.
Referenced by debug_new_recorder::_M_process(), alloc_mem(), check_leaks(), check_mem_corruption(), free_pointer(), operator delete(), and operator delete[]().
const char* new_progname = ((void *)0) |
Pointer to the program name. Its initial value is the macro _DEBUG_NEW_PROGNAME. You should try to assign the program path to it early in your application. Assigning argv[0]
to it in main is one way. If you use bash or ksh (or similar), the following statement is probably what you want: ‘new_progname = getenv("_");
’.
Definition at line 355 of file debug_new.cpp.
|
static |
List of all new'd pointers.
Definition at line 295 of file debug_new.cpp.
Referenced by alloc_mem(), check_leaks(), and check_mem_corruption().
|
static |
The mutex guard to protect simultaneous access to the pointer list.
Definition at line 317 of file debug_new.cpp.
Referenced by alloc_mem(), check_leaks(), check_mem_corruption(), and free_pointer().
bool new_verbose_flag = false |
Flag to control whether verbose messages are output.
Definition at line 338 of file debug_new.cpp.
Referenced by debug_new_recorder::_M_process(), alloc_mem(), check_leaks(), free_pointer(), operator delete(), operator delete[](), and debug_new_counter::~debug_new_counter().
stacktrace_print_callback_t stacktrace_print_callback = ((void *)0) |
Pointer to the callback used to print the stack backtrace in case of a memory problem. A null value causes the default stack trace printing routine to be used.
Definition at line 362 of file debug_new.cpp.
|
static |
Total memory allocated in bytes.
Definition at line 327 of file debug_new.cpp.
Referenced by alloc_mem(), and free_pointer().