Main Page   Reference Manual   Namespace List   Compound List   Namespace Members   Compound Members   File Members  

debugmalloc.h
Go to the documentation of this file.
1 // $Header$
2 //
3 // Copyright (C) 2000 - 2004, by
4 //
5 // Carlo Wood, Run on IRC <carlo@alinoe.com>
6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
8 //
9 // This file may be distributed under the terms of the Q Public License
10 // version 1.0 as appearing in the file LICENSE.QPL included in the
11 // packaging of this file.
12 //
13 
18 #ifndef LIBCWD_DEBUGMALLOC_H
19 #define LIBCWD_DEBUGMALLOC_H
20 
21 #ifndef LIBCWD_LIBRARIES_DEBUG_H
22 #error "Don't include <libcwd/debugmalloc.h> directly, include the appropriate \"debug.h\" instead."
23 #endif
24 
25 #ifndef LIBCWD_CONFIG_H
26 #include "config.h"
27 #endif
28 #ifndef LIBCWD_MACRO_ALLOCTAG_H
29 #include "macro_AllocTag.h"
30 #endif
31 
32 #if CWDEBUG_ALLOC
33 
34 #ifndef LIBCW_CSTDDEF
35 #define LIBCW_CSTDDEF
36 #include <cstddef> // Needed for size_t.
37 #endif
38 #ifndef LIBCWD_CLASS_ALLOC_H
39 #include "class_alloc.h"
40 #endif
41 #ifndef LIBCW_LOCKABLE_AUTO_PTR_H
42 #include "lockable_auto_ptr.h"
43 #endif
44 #ifndef LIBCWD_PRIVATE_SET_ALLOC_CHECKING_H
46 #endif
47 #ifndef LIBCWD_ENUM_MEMBLK_TYPES_H
48 #include "enum_memblk_types.h"
49 #endif
50 #if CWDEBUG_MARKER && !defined(LIBCWD_CLASS_MARKER_H)
51 #include "class_marker.h"
52 #endif
53 #ifndef LIBCWD_CLASS_ALLOC_FILTER_H
54 #include "class_alloc_filter.h"
55 #endif
56 #ifndef LIBCW_SYS_TIME_H
57 #define LIBCW_SYS_TIME_H
58 #include <sys/time.h> // Needed for struct timeval.
59 #endif
60 
61 namespace libcwd {
62 
64 enum malloc_report_nt
65 {
84  malloc_report
85 };
86 
87 // Backtrace hook:
88 int const max_frames = 16;
89 extern void (*backtrace_hook)(void** buffer, int frames LIBCWD_COMMA_TSD_PARAM);
90 
91 #ifndef LIBCWD_DOXYGEN
92 extern std::ostream& operator<<(std::ostream&, malloc_report_nt);
93 #endif
94 
95 // Accessors:
96 
97 extern size_t mem_size();
98 extern unsigned long mem_blocks();
99 extern alloc_ct const* find_alloc(void const* ptr);
100 extern bool test_delete(void const* ptr);
101 
102 // Manipulators:
103 extern void make_invisible(void const* ptr);
104 extern void make_all_allocations_invisible_except(void const* ptr);
127 inline void set_invisible_on() { LIBCWD_TSD_DECLARATION; _private_::set_invisible_on(LIBCWD_TSD); }
134 inline void set_invisible_off() { LIBCWD_TSD_DECLARATION; _private_::set_invisible_off(LIBCWD_TSD); }
135 #if CWDEBUG_MARKER
136 extern void move_outside(marker_ct*, void const* ptr);
137 #endif
138 
139 // Undocumented (libcwd `internal' function)
140 extern void init_debugmalloc();
141 
142 } // namespace libcwd
143 
144 #else // !CWDEBUG_ALLOC
145 
146 namespace libcwd {
147 
148 inline void make_invisible(void const*) { }
149 inline void make_all_allocations_invisible_except(void const*) { }
150 inline void set_invisible_on() { }
151 inline void set_invisible_off() { }
152 
153 } // namespace libcwd
154 
155 #endif // !CWDEBUG_ALLOC
156 
157 #if CWDEBUG_DEBUGM
158 #define LIBCWD_DEBUGM_CERR(x) DEBUGDEBUG_CERR(x)
159 #define LIBCWD_DEBUGM_ASSERT(expr) do { if (!(expr)) { FATALDEBUGDEBUG_CERR("CWDEBUG_DEBUGM: " __FILE__ ":" << __LINE__ << ": " << __PRETTY_FUNCTION__ << ": Assertion`" << LIBCWD_STRING(expr) << "' failed."); core_dump(); } } while(0)
160 #else
161 #define LIBCWD_DEBUGM_CERR(x) do { } while(0)
162 #define LIBCWD_DEBUGM_ASSERT(x) do { } while(0)
163 #endif
164 
165 namespace libcwd {
166 
167 #if CWDEBUG_ALLOC
168 extern unsigned long list_allocations_on(debug_ct& debug_object, alloc_filter_ct const& format);
169 extern unsigned long list_allocations_on(debug_ct& debug_object);
170 #else // !CWDEBUG_ALLOC
171 inline void list_allocations_on(debug_ct&) { }
172 #endif // !CWDEBUG_ALLOC
173 
174 } // namespace libcwd
175 
176 #ifndef LIBCWD_DEBUGMALLOC_INTERNAL
177 #if CWDEBUG_ALLOC
178 
179 #ifndef LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
180 // Ugh, use macro kludge.
181 #include <cstdlib> // Make sure the prototypes for malloc et al are declared
182  // before defining the macros!
183 #define malloc __libcwd_malloc
184 #define calloc __libcwd_calloc
185 #define realloc __libcwd_realloc
186 #define free __libcwd_free
187 #endif
188 
189 #ifndef LIBCWD_HAVE_DLOPEN
190 // Use macro kludge for these (too):
191 #if defined(LIBCWD_HAVE_POSIX_MEMALIGN) || defined(LIBCWD_HAVE_ALIGNED_ALLOC)
192 // Include this header before defining the macro 'posix_memalign' and/or 'aligned_alloc'.
193 #include <cstdlib>
194 #endif
195 #ifdef LIBCWD_HAVE_POSIX_MEMALIGN
196 #define posix_memalign __libcwd_posix_memalign
197 #endif
198 #ifdef LIBCWD_HAVE_ALIGNED_ALLOC
199 #define aligned_alloc __libcwd_aligned_alloc
200 #endif
201 // Include this header before defining the macro 'memalign' or 'valloc'.
202 #if defined(HAVE_MALLOC_H) && (defined(HAVE_MEMALIGN) || defined(HAVE_VALLOC))
203 #include <malloc.h>
204 #endif
205 #if defined(HAVE_UNISTD_H) && defined(HAVE_VALLOC)
206 #include <unistd.h> // This is what is needed for valloc(3) on FreeBSD. Also needed for sysconf.
207 #endif
208 #ifdef LIBCWD_HAVE_MEMALIGN
209 #define memalign __libcwd_memalign
210 #endif
211 #ifdef LIBCWD_HAVE_VALLOC
212 #define valloc __libcwd_valloc
213 #endif
214 #endif // !LIBCWD_HAVE_DLOPEN
215 
216 // Use external linkage to catch ALL calls to all malloc/calloc/realloc/free functions,
217 // also those that are done in libc, or any other shared library that might be linked.
218 // [ Note: if LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC wasn't defined, then these are the prototypes
219 // for __libcwd_malloc et al of course. We still use external "C" linkage in that case
220 // in order to avoid a collision with possibily later included prototypes for malloc. ]
221 extern "C" void* malloc(size_t size) throw() __attribute__((__malloc__));
222 extern "C" void* calloc(size_t nmemb, size_t size) throw() __attribute__((__malloc__));
223 extern "C" void* realloc(void* ptr, size_t size) throw() __attribute__((__malloc__));
224 extern "C" void free(void* ptr) throw();
225 #ifdef LIBCWD_HAVE_POSIX_MEMALIGN
226 #ifdef posix_memalign // Due to declaration conflicts with cstdlib, lets not define this when this isn't our macro.
227 extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size) throw() __attribute__((__nonnull__(1))) __wur;
228 #endif
229 #endif
230 #ifdef LIBCWD_HAVE_ALIGNED_ALLOC
231 extern "C" void* aligned_alloc(size_t alignment, size_t size) throw() __attribute__((__malloc__)) __attribute__((__alloc_size__(2))) __wur;
232 #endif
233 #ifdef LIBCWD_HAVE_VALLOC
234 extern "C" void* valloc(size_t size) throw() __attribute__((__malloc__)) __wur;
235 #endif
236 #ifdef LIBCWD_HAVE_MEMALIGN
237 extern "C" void* memalign(size_t boundary, size_t size) throw() __attribute__((__malloc__));
238 #endif
239 
240 #ifndef LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
241 // Use same kludge for other libc functions that return malloc-ed pointers.
242 #define strdup __libcwd_strdup
243 #ifdef HAVE_WMEMCPY
244 #define wcsdup __libcwd_wcsdup
245 #endif
246 
247 inline
248 char*
249 __libcwd_strdup(char const* str)
250 {
251  size_t size = strlen(str) + 1;
252  char* p = (char*)malloc(size);
253  if (p)
254  {
255  memcpy(p, str, size);
256  AllocTag(p, "strdup()");
257  }
258  return p;
259 }
260 
261 #ifdef HAVE_WMEMCPY
262 extern "C" {
263  size_t wcslen(wchar_t const*);
264  wchar_t* wmemcpy(wchar_t*, wchar_t const*, size_t);
265 }
266 
267 inline
268 wchar_t*
269 __libcwd_wcsdup(wchar_t const* str)
270 {
271  size_t size = wcslen(str) + 1;
272  wchar_t* p = (wchar_t*)malloc(size * sizeof(wchar_t));
273  if (p)
274  {
275  wmemcpy(p, str, size);
276  AllocTag(p, "wcsdup()");
277  }
278  return p;
279 }
280 #endif // HAVE_WMEMCPY
281 #endif // !LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
282 
283 #endif // CWDEBUG_ALLOC
284 #endif // !LIBCWD_DEBUGMALLOC_INTERNAL
285 
286 #endif // LIBCWD_DEBUGMALLOC_H
unsigned long mem_blocks()
Returns the total number of allocated memory blocks.
Definition: debugmalloc.cc:2933
bool test_delete(void const *void_ptr)
Test if a pointer points to the start of an allocated memory block.
Definition: debugmalloc.cc:2872
size_t mem_size()
Returns the total number of allocated bytes.
Definition: debugmalloc.cc:2907
channel_ct malloc
Definition: debug.cc:474
alloc_ct const * find_alloc(void const *ptr)
Find information about a memory allocation.
Definition: debugmalloc.cc:3641
void make_invisible(void const *void_ptr)
Make allocation pointed to by ptr invisible.
Definition: debugmalloc.cc:3159
void make_all_allocations_invisible_except(void const *ptr)
Make all current allocations invisible except the given pointer.
Definition: debugmalloc.cc:3219
void make_exit_function_list_invisible()
Make allocations done in libc.so:__new_exitfn invisible.
Definition: debugmalloc.cc:3262
void move_outside(marker_ct *marker, void const *void_ptr)
Move memory allocation pointed to by ptr outside marker.
Definition: debugmalloc.cc:3487
unsigned long list_allocations_on(debug_ct &debug_object)
List all current allocations to a given debug object.
Definition: debugmalloc.cc:3020
namespace for libcwd.
Definition: debug.cc:87
std::ostream & operator<<(std::ostream &os, memblk_types_nt memblk_type)
Allow writing a memblk_types_nt directly to an ostream.
Definition: debugmalloc.cc:688
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.