Implementation of debug versions of new and delete to check leakage. More...
#include <new>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "_nvwa.h"
#include "c++11.h"
#include "fast_mutex.h"
#include "static_assert.h"
#include "debug_new.h"
Classes | |
struct | nvwa::new_ptr_list_t |
Structure to store the position information where new occurs. More... | |
Namespaces | |
namespace | nvwa |
Defines | |
#define | _DEBUG_NEW_ALIGNMENT 16 |
The alignment requirement of allocated memory blocks. | |
#define | _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0) |
The expression to return the caller address. | |
#define | _DEBUG_NEW_ERROR_ACTION abort() |
The action to take when an error occurs. | |
#define | _DEBUG_NEW_FILENAME_LEN 44 |
The length of file name stored if greater than zero. | |
#define | _DEBUG_NEW_PROGNAME NULL |
The program (executable) name to be set at compile time. | |
#define | _DEBUG_NEW_STD_OPER_NEW 1 |
Macro to indicate whether the standard-conformant behaviour of operator new is wanted. | |
#define | _DEBUG_NEW_TAILCHECK 0 |
Macro to indicate whether a writing-past-end check will be performed. | |
#define | _DEBUG_NEW_TAILCHECK_CHAR 0xCC |
Value of the padding bytes at the end of a memory block. | |
#define | _DEBUG_NEW_USE_ADDR2LINE 1 |
Whether to use addr2line to convert a caller address to file/line information. | |
#define | _DEBUG_NEW_REDEFINE_NEW 0 |
Macro to indicate whether redefinition of new is wanted. | |
#define | ALIGN(s) (((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1)) |
Gets the aligned value of memory block size. | |
Functions | |
int | nvwa::check_leaks () |
Checks for memory leaks. | |
int | nvwa::check_mem_corruption () |
Checks for heap corruption. | |
void * | operator new (size_t size, const char *file, int line) |
Allocates memory with file/line information. | |
void * | operator new[] (size_t size, const char *file, int line) |
Allocates array memory with file/line information. | |
void * | operator new (size_t size) throw (std::bad_alloc) |
Allocates memory without file/line information. | |
void * | operator new[] (size_t size) throw (std::bad_alloc) |
Allocates array memory without file/line information. | |
void * | operator new (size_t size, const std::nothrow_t &) noexcept |
Allocates memory with no-throw guarantee. | |
void * | operator new[] (size_t size, const std::nothrow_t &) noexcept |
Allocates array memory with no-throw guarantee. | |
void | operator delete (void *ptr) noexcept |
Deallocates memory. | |
void | operator delete[] (void *ptr) noexcept |
Deallocates array memory. | |
void | operator delete (void *ptr, const char *file, int line) noexcept |
Placement deallocation function. | |
void | operator delete[] (void *ptr, const char *file, int line) noexcept |
Placement deallocation function. | |
void | operator delete (void *ptr, const std::nothrow_t &) noexcept |
Placement deallocation function. | |
void | operator delete[] (void *ptr, const std::nothrow_t &) noexcept |
Placement deallocation function. | |
Variables | |
const size_t | nvwa::PLATFORM_MEM_ALIGNMENT = sizeof(size_t) * 2 |
The platform memory alignment. |
Implementation of debug versions of new and delete to check leakage.
#define _DEBUG_NEW_ALIGNMENT 16 |
The alignment requirement of allocated memory blocks.
It must be a power of two.
#define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0) |
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.
#define _DEBUG_NEW_PROGNAME NULL |
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 |
Macro to indicate whether redefinition of new
is wanted.
If one wants to define one's own operator new
, or to call operator new
directly, it should be defined to 0
to alter the default behaviour. Unless, of course, one is willing to take the trouble to write something like:
# 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
Here it is defined to 0
to disable the redefinition of new
.
#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_TAILCHECK_CHAR 0xCC |
Value of the padding bytes at the end of a memory block.
#define _DEBUG_NEW_USE_ADDR2LINE 1 |
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)) |
Gets the aligned value of memory block size.
void operator delete | ( | void * | ptr, | |
const std::nothrow_t & | ||||
) |
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 |
void operator delete | ( | void * | ptr, | |
const char * | file, | |||
int | line | |||
) |
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 |
void operator delete | ( | void * | ptr | ) |
Deallocates memory.
ptr | pointer to the previously allocated memory |
void operator delete[] | ( | void * | ptr, | |
const std::nothrow_t & | ||||
) |
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 |
void operator delete[] | ( | void * | ptr, | |
const char * | file, | |||
int | line | |||
) |
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 |
void operator delete[] | ( | void * | ptr | ) |
Deallocates array memory.
ptr | pointer to the previously allocated memory |
void* operator new | ( | size_t | size, | |
const std::nothrow_t & | ||||
) |
Allocates memory with no-throw guarantee.
size | size of the required memory block |
NULL
if memory is insufficient void* operator new | ( | size_t | size | ) | throw (std::bad_alloc) |
Allocates memory without file/line information.
size | size of the required memory block |
NULL
if memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 0) bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
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 |
NULL
if memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 0) bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
void* operator new[] | ( | size_t | size, | |
const std::nothrow_t & | ||||
) |
Allocates array memory with no-throw guarantee.
size | size of the required memory block |
NULL
if memory is insufficient void* operator new[] | ( | size_t | size | ) | throw (std::bad_alloc) |
Allocates array memory without file/line information.
size | size of the required memory block |
NULL
if memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 0) bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |
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 |
NULL
if memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 0) bad_alloc | memory is insufficient (_DEBUG_NEW_STD_OPER_NEW is 1) |