debug_new.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
  2. // vim:tabstop=4:shiftwidth=4:expandtab:
  3. /*
  4. * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net>
  5. *
  6. * This software is provided 'as-is', without any express or implied
  7. * warranty. In no event will the authors be held liable for any
  8. * damages arising from the use of this software.
  9. *
  10. * Permission is granted to anyone to use this software for any purpose,
  11. * including commercial applications, and to alter it and redistribute
  12. * it freely, subject to the following restrictions:
  13. *
  14. * 1. The origin of this software must not be misrepresented; you must
  15. * not claim that you wrote the original software. If you use this
  16. * software in a product, an acknowledgement in the product
  17. * documentation would be appreciated but is not required.
  18. * 2. Altered source versions must be plainly marked as such, and must
  19. * not be misrepresented as being the original software.
  20. * 3. This notice may not be removed or altered from any source
  21. * distribution.
  22. *
  23. * This file is part of Stones of Nvwa:
  24. * http://sourceforge.net/projects/nvwa
  25. *
  26. */
  27. /*!
  28. * \file debug_new.h
  29. * \ingroup QxMemLeak
  30. *
  31. * Header file for checking leaks caused by unmatched new/delete.
  32. *
  33. * \version 4.4, 2007/12/31
  34. * \author Wu Yongwei
  35. *
  36. */
  37. #ifndef QT_NO_DEBUG
  38. #ifndef _QX_MODE_RELEASE
  39. #if _QX_USE_MEM_LEAK_DETECTION
  40. #ifndef _DEBUG_NEW_H
  41. #define _DEBUG_NEW_H
  42. #ifdef _MSC_VER
  43. #pragma once
  44. #endif
  45. #include <new>
  46. #include <stdio.h>
  47. #include <QxCommon/QxMacro.h>
  48. /**
  49. * @def HAVE_PLACEMENT_DELETE
  50. *
  51. * Macro to indicate whether placement delete operators are supported on
  52. * a certain compiler. Some compilers, like Borland C++ Compiler 5.5.1
  53. * and Digital Mars Compiler 8.42, do not support them, and the user
  54. * must define this macro to \c 0 to make the program compile. Also
  55. * note that in that case memory leakage will occur if an exception is
  56. * thrown in the initialization (constructor) of a dynamically created
  57. * object.
  58. */
  59. #ifndef HAVE_PLACEMENT_DELETE
  60. #define HAVE_PLACEMENT_DELETE 1
  61. #endif
  62. /**
  63. * @def _DEBUG_NEW_REDEFINE_NEW
  64. *
  65. * Macro to indicate whether redefinition of \c new is wanted. If one
  66. * wants to define one's own <code>operator new</code>, to call
  67. * <code>operator new</code> directly, or to call placement \c new, it
  68. * should be defined to \c 0 to alter the default behaviour. Unless, of
  69. * course, one is willing to take the trouble to write something like:
  70. * @code
  71. * # ifdef new
  72. * # define _NEW_REDEFINED
  73. * # undef new
  74. * # endif
  75. *
  76. * // Code that uses new is here
  77. *
  78. * # ifdef _NEW_REDEFINED
  79. * # ifdef DEBUG_NEW
  80. * # define new DEBUG_NEW
  81. * # endif
  82. * # undef _NEW_REDEFINED
  83. * # endif
  84. * @endcode
  85. */
  86. #ifndef _DEBUG_NEW_REDEFINE_NEW
  87. #define _DEBUG_NEW_REDEFINE_NEW 1
  88. #endif
  89. /**
  90. * @def _DEBUG_NEW_CALLER_ADDRESS
  91. *
  92. * The expression to return the caller address. print_position will
  93. * later on use this address to print the position information of memory
  94. * operation points.
  95. */
  96. #ifndef _DEBUG_NEW_CALLER_ADDRESS
  97. #ifdef __GNUC__
  98. #define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0)
  99. #else
  100. #define _DEBUG_NEW_CALLER_ADDRESS NULL
  101. #endif
  102. #endif
  103. /**
  104. * @def DEBUG_NEW
  105. *
  106. * Macro to catch file/line information on allocation. If
  107. * #_DEBUG_NEW_REDEFINE_NEW is \c 0, one can use this macro directly;
  108. * otherwise \c new will be defined to it, and one must use \c new
  109. * instead.
  110. */
  111. #define DEBUG_NEW qx::memory::__debug_new_recorder(__FILE__, __LINE__, __FUNCTION__) ->* new
  112. #if _DEBUG_NEW_REDEFINE_NEW
  113. #define new DEBUG_NEW
  114. #endif // _DEBUG_NEW_REDEFINE_NEW
  115. #ifdef _DEBUG_NEW_EMULATE_MALLOC
  116. #include <stdlib.h>
  117. #ifdef new
  118. #define malloc(s) ((void*)(new char[s]))
  119. #else // new
  120. #define malloc(s) ((void*)(DEBUG_NEW char[s]))
  121. #endif // new
  122. #define free(p) delete[] (char*)(p)
  123. #endif // _DEBUG_NEW_EMULATE_MALLOC
  124. QX_DLL_EXPORT void * operator new(size_t size, const char * file, int line);
  125. QX_DLL_EXPORT void * operator new[](size_t size, const char * file, int line);
  126. #if HAVE_PLACEMENT_DELETE
  127. QX_DLL_EXPORT void operator delete(void * pointer, const char * file, int line) throw();
  128. QX_DLL_EXPORT void operator delete[](void * pointer, const char * file, int line) throw();
  129. #endif
  130. #if defined(_MSC_VER) && _MSC_VER < 1300
  131. // MSVC 6 requires the following declarations; or the non-placement
  132. // new[]/delete[] will not compile.
  133. QX_DLL_EXPORT void * operator new[](size_t) throw(std::bad_alloc);
  134. QX_DLL_EXPORT void operator delete[](void *) throw();
  135. #endif
  136. namespace qx {
  137. namespace memory {
  138. /* Prototypes */
  139. QX_DLL_EXPORT int check_leaks();
  140. QX_DLL_EXPORT int check_mem_corruption();
  141. /* Control variables */
  142. extern bool new_autocheck_flag; // default to true: call check_leaks() on exit
  143. extern bool new_verbose_flag; // default to false: no verbose information
  144. extern FILE* new_output_fp; // default to stderr: output to console
  145. extern const char* new_progname;// default to NULL; should be assigned argv[0]
  146. /**
  147. * Recorder class to remember the call context.
  148. *
  149. * 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.
  150. */
  151. class QX_DLL_EXPORT __debug_new_recorder
  152. {
  153. const char* _M_file;
  154. const int _M_line;
  155. const char* _M_fct;
  156. void _M_process(void* pointer);
  157. public:
  158. /**
  159. * Constructor to remember the call context. The information will
  160. * be used in __debug_new_recorder::operator->*.
  161. */
  162. __debug_new_recorder(const char* file, int line, const char* fct)
  163. : _M_file(file), _M_line(line), _M_fct(fct) {}
  164. /**
  165. * Operator to write the context information to memory.
  166. * <code>operator->*</code> is chosen because it has the right
  167. * precedence, it is rarely used, and it looks good: so people can
  168. * tell the special usage more quickly.
  169. */
  170. template <class _Tp> _Tp* operator->*(_Tp* pointer) { _M_process(pointer); return pointer; };
  171. static void free_pointer(void* pointer, void* addr, bool is_array);
  172. private:
  173. __debug_new_recorder(const __debug_new_recorder&);
  174. __debug_new_recorder& operator=(const __debug_new_recorder&);
  175. };
  176. /**
  177. * Counter class for on-exit leakage check.
  178. *
  179. * This technique is learnt from <em>The C++ Programming Language</em> by
  180. * Bjarne Stroustup.
  181. */
  182. class QX_DLL_EXPORT __debug_new_counter
  183. {
  184. static int _S_count;
  185. public:
  186. __debug_new_counter();
  187. ~__debug_new_counter();
  188. };
  189. /** Counting object for each file including debug_new.h. */
  190. static __debug_new_counter __debug_new_count;
  191. } // namespace memory
  192. } // namespace qx
  193. #endif // _DEBUG_NEW_H
  194. #endif // _QX_USE_MEM_LEAK_DETECTION
  195. #endif // _QX_MODE_RELEASE
  196. #endif // QT_NO_DEBUG