libcwd: The C++ Debugging Support Library - Reference Manual
Author: Carlo Wood
Description: C++ debugging support library with ostream debug output
Keywords: libcwd, debug output, debug facility, debug channel, object orientation, OO, C++, nested debug output, ostream, memory allocation, debugging, source file and line number

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

# libcwd/debugmalloc.h

Go to the documentation of this file.

    00001 // $Header$
    00002 //
    00003 // Copyright (C) 2000 - 2004, by
    00004 //
    00005 // Carlo Wood, Run on IRC <carlo@alinoe.com>
    00006 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
    00007 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
    00008 //
    00009 // This file may be distributed under the terms of the Q Public License
    00010 // version 1.0 as appearing in the file LICENSE.QPL included in the
    00011 // packaging of this file.
    00012 //
    00013
    00018 #ifndef LIBCWD_DEBUGMALLOC_H
    00019 #define LIBCWD_DEBUGMALLOC_H
    00020
    00021 #ifndef LIBCWD_LIBRARIES_DEBUG_H
    00022 #error "Don't include <libcwd/debugmalloc.h> directly, include the appropriate \"debug.h\" instead."
    00023 #endif
    00024
    00025 #ifndef LIBCWD_CONFIG_H
    00026 #include <libcwd/config.h>
    00027 #endif
    00028 #ifndef LIBCWD_MACRO_ALLOCTAG_H
    00029 #include <libcwd/macro_AllocTag.h>
    00030 #endif
    00031
    00032 #if CWDEBUG_ALLOC
    00033
    00034 #ifndef LIBCW_CSTDDEF
    00035 #define LIBCW_CSTDDEF
    00036 #include <cstddef>              // Needed for size_t.
    00037 #endif
    00038 #ifndef LIBCWD_CLASS_ALLOC_H
    00039 #include <libcwd/class_alloc.h>
    00040 #endif
    00041 #ifndef LIBCW_LOCKABLE_AUTO_PTR_H
    00042 #include <libcwd/lockable_auto_ptr.h>
    00043 #endif
    00044 #ifndef LIBCWD_PRIVATE_SET_ALLOC_CHECKING_H
    00045 #include <libcwd/private_set_alloc_checking.h>
    00046 #endif
    00047 #ifndef LIBCWD_ENUM_MEMBLK_TYPES_H
    00048 #include <libcwd/enum_memblk_types.h>
    00049 #endif
    00050 #if CWDEBUG_MARKER && !defined(LIBCWD_CLASS_MARKER_H)
    00051 #include <libcwd/class_marker.h>
    00052 #endif
    00053 #ifndef LIBCWD_CLASS_ALLOC_FILTER_H
    00054 #include <libcwd/class_alloc_filter.h>
    00055 #endif
    00056 #ifndef LIBCW_SYS_TIME_H
    00057 #define LIBCW_SYS_TIME_H
    00058 #include <sys/time.h>           // Needed for struct timeval.
    00059 #endif
    00060
    00061 namespace libcwd {
    00062
    00064 enum malloc_report_nt
    00065 {
    00084   malloc_report
    00085 };
    00086
    00087 // Backtrace hook:
    00088 int const max_frames = 16;
    00089 extern void (*backtrace_hook)(void** buffer, int frames LIBCWD_COMMA_TSD_PARAM);
    00090
    00091 #ifndef LIBCWD_DOXYGEN
    00092 extern std::ostream& operator<<(std::ostream&, malloc_report_nt);
    00093 #endif
    00094
    00095 // Accessors:
    00096
    00097 extern size_t mem_size(void);
    00098 extern unsigned long mem_blocks(void);
    00099 extern alloc_ct const* find_alloc(void const* ptr);
    00100 extern bool test_delete(void const* ptr);
    00101
    00102 // Manipulators:
    00103 extern void make_invisible(void const* ptr);
    00104 extern void make_all_allocations_invisible_except(void const* ptr);
    00105 extern void make_exit_function_list_invisible(void);
    00127 inline void set_invisible_on(void) { LIBCWD_TSD_DECLARATION; _private_::set_invisible_on(LIBCWD_TSD); }
    00134 inline void set_invisible_off(void) { LIBCWD_TSD_DECLARATION; _private_::set_invisible_off(LIBCWD_TSD); }
    00135 #if CWDEBUG_MARKER
    00136 extern void move_outside(marker_ct*, void const* ptr);
    00137 #endif
    00138
    00139 // Undocumented (libcwd `internal' function)
    00140 extern void init_debugmalloc(void);
    00141
    00142 } // namespace libcwd
    00143
    00144 #else // !CWDEBUG_ALLOC
    00145
    00146 namespace libcwd {
    00147
    00148 inline void make_invisible(void const*) { }
    00149 inline void make_all_allocations_invisible_except(void const*) { }
    00150 inline void set_invisible_on(void) { }
    00151 inline void set_invisible_off(void) { }
    00152
    00153 } // namespace libcwd
    00154
    00155 #endif // !CWDEBUG_ALLOC
    00156
    00157 #if CWDEBUG_DEBUGM
    00158 #define LIBCWD_DEBUGM_CERR(x) DEBUGDEBUG_CERR(x)
    00159 #else
    00160 #define LIBCWD_DEBUGM_CERR(x)
    00161 #endif
    00162
    00163 namespace libcwd {
    00164
    00165 #if CWDEBUG_ALLOC
    00166 extern unsigned long list_allocations_on(debug_ct& debug_object, alloc_filter_ct const& format);
    00167 extern unsigned long list_allocations_on(debug_ct& debug_object);
    00168 #else // !CWDEBUG_ALLOC
    00169 inline void list_allocations_on(debug_ct&) { }
    00170 #endif // !CWDEBUG_ALLOC
    00171
    00172 } // namespace libcwd
    00173
    00174 #ifndef LIBCWD_DEBUGMALLOC_INTERNAL
    00175 #if CWDEBUG_ALLOC
    00176
    00177 #ifndef LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
    00178 // Ugh, use macro kludge.
    00179 #include <cstdlib>      // Make sure the prototypes for malloc et al are declared
    00180                         // before defining the macros!
    00181 #define malloc __libcwd_malloc
    00182 #define calloc __libcwd_calloc
    00183 #define realloc __libcwd_realloc
    00184 #define free __libcwd_free
    00185 #endif
    00186
    00187 #ifndef LIBCWD_HAVE_DLOPEN
    00188 // Use macro kludge for these (too):
    00189 #ifdef LIBCWD_HAVE_POSIX_MEMALIGN
    00190 // Include this header before defining the macro 'posix_memalign'.
    00191 #include <cstdlib>
    00192 #define posix_memalign __libcwd_posix_memalign
    00193 #endif
    00194 // Include this header before defining the macro 'memalign' or 'valloc'.
    00195 #if defined(HAVE_MALLOC_H) && (defined(HAVE_MEMALIGN) || defined(HAVE_VALLOC))
    00196 #include <malloc.h>
    00197 #endif
    00198 #if defined(HAVE_UNISTD_H) && defined(HAVE_VALLOC)
    00199 #include <unistd.h>             // This is what is needed for valloc(3) on FreeBSD. Also needed for sysconf.
    00200 #endif
    00201 #ifdef LIBCWD_HAVE_MEMALIGN
    00202 #define memalign __libcwd_memalign
    00203 #endif
    00204 #ifdef LIBCWD_HAVE_VALLOC
    00205 #define valloc __libcwd_valloc
    00206 #endif
    00207 #endif // !LIBCWD_HAVE_DLOPEN
    00208
    00209 // Use external linkage to catch ALL calls to all malloc/calloc/realloc/free functions,
    00210 // also those that are done in libc, or any other shared library that might be linked.
    00211 // [ Note: if LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC wasn't defined, then these are the prototypes
    00212 // for __libcwd_malloc et al of course.  We still use external "C" linkage in that case
    00213 // in order to avoid a collision with possibily later included prototypes for malloc. ]
    00214 extern "C" void* malloc(size_t size) throw() __attribute__((__malloc__));
    00215 extern "C" void* calloc(size_t nmemb, size_t size) throw() __attribute__((__malloc__));
    00216 extern "C" void* realloc(void* ptr, size_t size) throw() __attribute__((__malloc__));
    00217 extern "C" void  free(void* ptr) throw();
    00218 #ifdef LIBCWD_HAVE_POSIX_MEMALIGN
    00219 extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size) throw();
    00220 #endif
    00221 #ifdef LIBCWD_HAVE_VALLOC
    00222 extern "C" void *valloc(size_t size) throw() __attribute__((__malloc__));
    00223 #endif
    00224 #ifdef LIBCWD_HAVE_MEMALIGN
    00225 extern "C" void *memalign(size_t boundary, size_t size) throw() __attribute__((__malloc__));
    00226 #endif
    00227
    00228 #ifndef LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
    00229 // Use same kludge for other libc functions that return malloc-ed pointers.
    00230 #define strdup __libcwd_strdup
    00231 #ifdef HAVE_WMEMCPY
    00232 #define wcsdup __libcwd_wcsdup
    00233 #endif
    00234
    00235 inline
    00236 char*
    00237 __libcwd_strdup(char const* str)
    00238 {
    00239   size_t size = strlen(str) + 1;
    00240   char* p = (char*)malloc(size);
    00241   if (p)
    00242   {
    00243     memcpy(p, str, size);
    00244     AllocTag(p, "strdup()");
    00245   }
    00246   return p;
    00247 }
    00248
    00249 #ifdef HAVE_WMEMCPY
    00250 extern "C" {
    00251   size_t wcslen(wchar_t const*);
    00252   wchar_t* wmemcpy(wchar_t*, wchar_t const*, size_t);
    00253 }
    00254
    00255 inline
    00256 wchar_t*
    00257 __libcwd_wcsdup(wchar_t const* str)
    00258 {
    00259   size_t size = wcslen(str) + 1;
    00260   wchar_t* p = (wchar_t*)malloc(size * sizeof(wchar_t));
    00261   if (p)
    00262   {
    00263     wmemcpy(p, str, size);
    00264     AllocTag(p, "wcsdup()");
    00265   }
    00266   return p;
    00267 }
    00268 #endif // HAVE_WMEMCPY
    00269 #endif // !LIBCWD_USE_EXTERNAL_C_LINKAGE_FOR_MALLOC
    00270
    00271 #endif // CWDEBUG_ALLOC
    00272 #endif // !LIBCWD_DEBUGMALLOC_INTERNAL
    00273
    00274 #endif // LIBCWD_DEBUGMALLOC_H