dumapp.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * DUMA - Red-Zone memory allocator.
  3. * Copyright (C) 2002-2009 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
  4. * Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
  5. * License: GNU GPL (GNU General Public License, see COPYING-GPL)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. *
  22. * FILE CONTENTS:
  23. * internal implementation file
  24. * replaces various global C++ new/delete/new[]/delete[] operators
  25. */
  26. #ifndef DUMA_NO_CPP_SUPPORT
  27. #ifdef _MSC_VER
  28. #include <new.h>
  29. #include <new>
  30. #else
  31. #include <new>
  32. #endif
  33. #include <stdlib.h>
  34. #include "dumapp.h"
  35. #include "noduma.h"
  36. /* define the global variables */
  37. static const char unknown_cxx_file[] =
  38. "UNKNOWN (use #include \"dumapp.h\")";
  39. #ifndef DUMA_NO_LEAKDETECTION
  40. /* with Leak-Detection */
  41. #define DUMA_PARAMS_UK , unknown_cxx_file, 0
  42. #define DUMA_PARAMS_FILELINE , filename, lineno
  43. #else
  44. /* no Leak-Detection */
  45. #define DUMA_PARAMS_UK
  46. #define DUMA_PARAMS_FILELINE
  47. #endif
  48. /********************************************************************
  49. ********************************************************************/
  50. #ifdef _MSC_VER
  51. int DUMA_CDECL duma_new_handler( size_t size ) { return 0; }
  52. #else
  53. void duma_new_handler() { }
  54. #endif
  55. // declare function ; needed for attribute
  56. static
  57. #ifdef _MSC_VER
  58. __forceinline
  59. #else
  60. inline
  61. #endif
  62. void * duma_new_operator(DUMA_SIZE_T userSize, enum _DUMA_Allocator allocator, bool dothrow
  63. #ifndef DUMA_NO_LEAKDETECTION
  64. , const char * filename, int lineno
  65. #endif
  66. )
  67. #ifdef __GNUC__
  68. __attribute__ ((always_inline))
  69. #endif
  70. ;
  71. /* Function: duma_new_operator
  72. *
  73. * C++ allocation function,
  74. * which is nearly C++ conform.
  75. *
  76. * Missing features are:
  77. *
  78. * - check if new_handler function hangs, return NULL or throw bad_alloc() in this case
  79. * on UNIX systems alarm() may be usable
  80. *
  81. * Following features are implemented:
  82. *
  83. * - loop is done
  84. * - alignment depends on user
  85. * - bad_alloc() exception will be thrown
  86. * - bad_alloc() is catched to return (void*)0
  87. * - check for userSize == 0, return non-NULL in this case
  88. * implemented in new/delete operators below
  89. *
  90. */
  91. void * duma_new_operator(DUMA_SIZE_T userSize, enum _DUMA_Allocator allocator, bool dothrow
  92. #ifndef DUMA_NO_LEAKDETECTION
  93. , const char * filename, int lineno
  94. #endif
  95. )
  96. {
  97. void * ret = 0;
  98. #ifdef _MSC_VER
  99. int pnhret = 1;
  100. #else
  101. #define pnhret 1
  102. #endif
  103. // initialize duma?
  104. if ( _duma_g.allocList == 0 )
  105. _duma_init(); /* This sets DUMA_ALIGNMENT, DUMA_PROTECT_BELOW, DUMA_FILL, ... */
  106. DUMA_TLSVARS_T * duma_tls = GET_DUMA_TLSVARS();
  107. do
  108. {
  109. // try allocation
  110. ret = _duma_allocate( 0 /*=alignment*/
  111. , userSize
  112. , duma_tls->PROTECT_BELOW
  113. , duma_tls->FILL
  114. , 1 /*=protectAllocList*/
  115. , allocator
  116. , DUMA_FAIL_NULL
  117. #ifndef DUMA_NO_LEAKDETECTION
  118. , filename
  119. , lineno
  120. #endif
  121. );
  122. // when allocation failed (and last call to new_handler didn't fail on Visual C++)
  123. if ( !ret && pnhret )
  124. {
  125. // get the current new_handler
  126. #ifdef _MSC_VER
  127. _PNH h = _set_new_handler(duma_new_handler);
  128. _set_new_handler(h);
  129. #else
  130. std::new_handler h = std::set_new_handler(duma_new_handler);
  131. std::set_new_handler(h);
  132. #endif
  133. // is there any handler?
  134. if ( h )
  135. {
  136. try // new_handler may throw an exception!!!
  137. {
  138. // call handler
  139. #ifdef _MSC_VER
  140. pnhret = h(userSize);
  141. #else
  142. h();
  143. #endif
  144. }
  145. catch (std::bad_alloc) // error occured in new_handler
  146. {
  147. if (dothrow) throw; // report error via re-throwing
  148. else return ret; // report error via (void*)0
  149. } // end try catch
  150. }
  151. else if (dothrow) // report non-existing handler via exception
  152. throw std::bad_alloc();
  153. else // report non-existing handler via (void*)0
  154. return ret;
  155. }
  156. } while ( !ret ); // loop until memory is claimed
  157. return ret;
  158. }
  159. /********************************************************************
  160. ********************************************************************/
  161. /* Function: operator new
  162. *
  163. * Single object form, no debug information
  164. * (11) = (a) ; ASW
  165. */
  166. void * DUMA_CDECL operator new( DUMA_SIZE_T size ) NEW_THROW_SPEC
  167. {
  168. return duma_new_operator(size, EFA_NEW_ELEM, true DUMA_PARAMS_UK);
  169. }
  170. /* Function: operator new
  171. *
  172. * Single object form, no debug information
  173. * (12) = (b) ; ASN
  174. */
  175. void * DUMA_CDECL operator new( DUMA_SIZE_T size, const std::nothrow_t & )
  176. throw()
  177. {
  178. return duma_new_operator(size, EFA_NEW_ELEM, false DUMA_PARAMS_UK);
  179. }
  180. /* Function: operator delete
  181. *
  182. * Single object form, no debug information
  183. * (13) = ( c ) ; FSW
  184. */
  185. void DUMA_CDECL operator delete( void *ptr )
  186. throw()
  187. {
  188. #ifndef DUMA_NO_LEAKDETECTION
  189. DUMA_TLSVARS_T & duma_tls = * GET_DUMA_TLSVARS();
  190. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM, duma_tls.DelFile[duma_tls.DelPtr], duma_tls.DelLine[duma_tls.DelPtr]);
  191. #else
  192. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM DUMA_PARAMS_UK);
  193. #endif
  194. }
  195. /* Function: operator delete
  196. *
  197. * Single object form, no debug information
  198. * (14) = (d) ; FSN
  199. */
  200. void DUMA_CDECL operator delete( void * ptr, const std::nothrow_t & )
  201. throw()
  202. {
  203. #ifndef DUMA_NO_LEAKDETECTION
  204. DUMA_TLSVARS_T & duma_tls = * GET_DUMA_TLSVARS();
  205. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM, duma_tls.DelFile[duma_tls.DelPtr], duma_tls.DelLine[duma_tls.DelPtr]);
  206. #else
  207. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM DUMA_PARAMS_UK);
  208. #endif
  209. }
  210. /********************************************************************
  211. ********************************************************************/
  212. /* 2x : ARRAY OBJECT FORM - NO DEBUG INFORMATION */
  213. /* Function: operator new[]
  214. *
  215. * Array object form, no debug information
  216. * (21) = (a) ; AAW
  217. */
  218. void * DUMA_CDECL operator new[]( DUMA_SIZE_T size ) NEW_THROW_SPEC
  219. {
  220. return duma_new_operator(size, EFA_NEW_ARRAY, true DUMA_PARAMS_UK);
  221. }
  222. /* Function: operator new[]
  223. *
  224. * Array object form, no debug information
  225. * (22) = (b) ; AAN
  226. */
  227. void * DUMA_CDECL operator new[]( DUMA_SIZE_T size, const std::nothrow_t & )
  228. throw()
  229. {
  230. return duma_new_operator(size, EFA_NEW_ARRAY, false DUMA_PARAMS_UK);
  231. }
  232. /* Function: operator delete[]
  233. *
  234. * Array object form, no debug information
  235. * (23) = (c) ; FAW
  236. */
  237. void DUMA_CDECL operator delete[]( void * ptr )
  238. throw()
  239. {
  240. #ifndef DUMA_NO_LEAKDETECTION
  241. DUMA_TLSVARS_T & duma_tls = * GET_DUMA_TLSVARS();
  242. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY, duma_tls.DelFile[duma_tls.DelPtr], duma_tls.DelLine[duma_tls.DelPtr]);
  243. #else
  244. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY DUMA_PARAMS_UK);
  245. #endif
  246. }
  247. /* Function: operator delete[]
  248. *
  249. * Array object form, no debug information
  250. * (24) = (d) ; FAN
  251. */
  252. void DUMA_CDECL operator delete[]( void * ptr, const std::nothrow_t & )
  253. throw()
  254. {
  255. #ifndef DUMA_NO_LEAKDETECTION
  256. DUMA_TLSVARS_T & duma_tls = * GET_DUMA_TLSVARS();
  257. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY, duma_tls.DelFile[duma_tls.DelPtr], duma_tls.DelLine[duma_tls.DelPtr]);
  258. #else
  259. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY DUMA_PARAMS_UK);
  260. #endif
  261. }
  262. /********************************************************************
  263. ********************************************************************/
  264. #ifndef DUMA_NO_LEAKDETECTION
  265. /* 3x : SINGLE OBJECT FORM - WITH DEBUG INFORMATION */
  266. /* Function: operator new
  267. *
  268. * Single object form with debug information
  269. * (31) = (a) ; ASW
  270. */
  271. void * DUMA_CDECL operator new( DUMA_SIZE_T size, const char *filename, int lineno ) NEW_THROW_SPEC
  272. {
  273. return duma_new_operator(size, EFA_NEW_ELEM, true DUMA_PARAMS_FILELINE);
  274. }
  275. /* Function: operator new
  276. *
  277. * Single object form with debug information
  278. * (32) = (b) ; ASN
  279. */
  280. void * DUMA_CDECL operator new( DUMA_SIZE_T size, const std::nothrow_t &, const char *filename, int lineno )
  281. throw()
  282. {
  283. return duma_new_operator(size, EFA_NEW_ELEM, false DUMA_PARAMS_FILELINE);
  284. }
  285. /* Function: operator delete
  286. *
  287. * Single object form with debug information
  288. * (33) = (c) ; FSW
  289. */
  290. void DUMA_CDECL operator delete( void *ptr, const char *filename, int lineno )
  291. throw()
  292. {
  293. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM DUMA_PARAMS_FILELINE);
  294. }
  295. /* Function: operator delete
  296. *
  297. * Single object form with debug information
  298. * (34) = (d) ; FSN
  299. */
  300. void DUMA_CDECL operator delete( void *ptr, const std::nothrow_t &, const char *filename, int lineno )
  301. throw()
  302. {
  303. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ELEM DUMA_PARAMS_FILELINE);
  304. }
  305. /********************************************************************
  306. ********************************************************************/
  307. /* 4x : ARRAY OBJECT FORM - WITH DEBUG INFORMATION */
  308. /* Function: operator new[]
  309. *
  310. * Array object form with debug information
  311. * (41) = (a) ; AAW
  312. */
  313. void * DUMA_CDECL operator new[]( DUMA_SIZE_T size, const char *filename, int lineno ) NEW_THROW_SPEC
  314. {
  315. return duma_new_operator(size, EFA_NEW_ARRAY, true DUMA_PARAMS_FILELINE);
  316. }
  317. /* Function: operator new[]
  318. *
  319. * Array object form with debug information
  320. * (42) = (b) ; AAN
  321. */
  322. void * DUMA_CDECL operator new[]( DUMA_SIZE_T size, const std::nothrow_t &, const char *filename, int lineno )
  323. throw()
  324. {
  325. return duma_new_operator(size, EFA_NEW_ARRAY, false DUMA_PARAMS_FILELINE);
  326. }
  327. /* Function: operator delete[]
  328. *
  329. * Array object form with debug information
  330. * (43) = (c) ; FAW
  331. */
  332. void DUMA_CDECL operator delete[]( void *ptr, const char *filename, int lineno )
  333. throw()
  334. {
  335. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY DUMA_PARAMS_FILELINE);
  336. }
  337. /* Function: operator delete[]
  338. *
  339. * Array object form with debug information
  340. * (44) = (d) ; FAN
  341. */
  342. void DUMA_CDECL operator delete[]( void *ptr, const std::nothrow_t &, const char *filename, int lineno )
  343. throw()
  344. {
  345. _duma_deallocate(ptr, 1 /*=protectAllocList*/, EFA_DEL_ARRAY DUMA_PARAMS_FILELINE);
  346. }
  347. #endif /* end ifdef DUMA_NO_LEAKDETECTION */
  348. #endif /* DUMA_NO_CPP_SUPPORT */