"Fossies" - the Fresh Open Source Software Archive

Member "heaplayers-351/allocators/vam/tools/malloctrace.h" (2 Jan 2006, 6270 Bytes) of package /linux/misc/old/heaplayers_3_5_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "malloctrace.h" see the Fossies "Dox" file reference documentation.

    1 // -*- C++ -*-
    2 
    3 #ifndef _MALLOCTRACE_H_
    4 #define _MALLOCTRACE_H_
    5 
    6 #include <dlfcn.h>
    7 #include <stdlib.h>
    8 
    9 #include <map>
   10 #include <new>
   11 
   12 #include "heaplayers.h"
   13 #include "vamcommon.h"
   14 
   15 #define PRINT_TRACE         1
   16 #define PRINT_TIMESTAMP     0
   17 
   18 
   19 // PosixRecursiveLockType: recursive lock
   20 class PosixRecursiveLockType {
   21 
   22 public:
   23 
   24     PosixRecursiveLockType() {
   25         pthread_mutexattr_t attr;
   26         pthread_mutexattr_init(&attr);
   27         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
   28         pthread_mutex_init(&mutex, &attr);
   29     }
   30   
   31     ~PosixRecursiveLockType() {
   32         pthread_mutex_destroy(&mutex);
   33     }
   34   
   35     void lock() {
   36         pthread_mutex_lock(&mutex);
   37     }
   38   
   39     void unlock() {
   40         pthread_mutex_unlock(&mutex);
   41     }
   42   
   43 private:
   44 
   45     pthread_mutex_t mutex;
   46 
   47 };  // end of class PosixRecursiveLockType
   48 
   49 
   50 class MallocTracer {
   51 
   52 public:
   53 
   54     void * calloc(size_t nmemb, size_t size) {
   55         MallocTracerLock l(_lock);
   56 
   57         // deny memory allocation from dlsym, it'll use static buffer
   58         if (_in_dlsym)
   59             return NULL;
   60 
   61         if (_real_calloc == NULL)
   62             init_all();
   63 
   64         void * rv = NULL;
   65         Header * header = (Header *)(*_real_calloc)(nmemb, sizeof(Header) + size);
   66         if (header != NULL) {
   67             header->size = size;
   68             _memEverRequested += size;
   69             _memCurrRequested += size;
   70             rv = header + 1;
   71         }
   72 
   73         trace_printf("%u %u c %p %u %u\n", _memEverRequested, _memCurrRequested, rv, nmemb, size);
   74         return rv;
   75     }
   76 
   77     void * malloc(size_t size) {
   78         MallocTracerLock l(_lock);
   79 
   80         if (_real_malloc == NULL)
   81             init_all();
   82 
   83         void * rv = NULL;
   84         Header * header = (Header *)(*_real_malloc)(sizeof(Header) + size);
   85         if (header != NULL) {
   86             header->size = size;
   87             _memEverRequested += size;
   88             _memCurrRequested += size;
   89             rv = header + 1;
   90         }
   91 
   92         trace_printf("%u %u m %p %u\n", _memEverRequested, _memCurrRequested, rv, size);
   93         return rv;
   94     }
   95 
   96     void free(void * ptr) {
   97         MallocTracerLock l(_lock);
   98 
   99         if (_real_free == NULL)
  100             init_all();
  101 
  102         size_t size = 0;
  103         if (ptr != NULL) {
  104             Header * header = (Header *) ptr - 1;
  105             size = header->size;
  106             _memCurrRequested -= header->size;
  107             (*_real_free)(header);
  108         }
  109 
  110         trace_printf("%u %u f %p %u\n", _memEverRequested, _memCurrRequested, ptr, size);
  111     }
  112 
  113     void * realloc(void * ptr, size_t size) {
  114         MallocTracerLock l(_lock);
  115 
  116         if (_real_realloc == NULL)
  117             init_all();
  118 
  119         void * rv = NULL;
  120         Header * header = NULL;
  121         if (ptr != NULL) {
  122             header = (Header *) ptr - 1;
  123             _memCurrRequested -= header->size;
  124         }
  125 
  126         header = (Header *)(*_real_realloc)(header, sizeof(Header) + size);
  127         if (header != NULL) {
  128             header->size = size;
  129             _memEverRequested += size;
  130             _memCurrRequested += size;
  131             rv = header + 1;
  132         }
  133 
  134         trace_printf("%u %u r %p %p %u\n", _memEverRequested, _memCurrRequested, rv, ptr, size);
  135         return rv;
  136     }
  137 
  138     inline static MallocTracer * getMallocTracer() {
  139         static char buf[sizeof(MallocTracer)];
  140         static MallocTracer * mt = new (buf) MallocTracer;
  141         return mt;
  142     }
  143 
  144 private:
  145 
  146     struct Header {
  147         size_t size;
  148         size_t dummy;
  149     };
  150 
  151     typedef void * callocType (size_t, size_t);
  152     typedef void * mallocType (size_t);
  153     typedef void freeType (void * ptr);
  154     typedef void * reallocType (void *, size_t);
  155 
  156     typedef HL::Guard<PosixRecursiveLockType> MallocTracerLock;
  157 
  158     PosixRecursiveLockType _lock;
  159 
  160     bool _in_dlsym;
  161 
  162     callocType * _real_calloc;
  163     mallocType * _real_malloc;
  164     freeType * _real_free;
  165     reallocType * _real_realloc;
  166 
  167     size_t _memEverRequested;
  168     size_t _memCurrRequested;
  169 
  170     static __thread int _trace_fd;
  171 
  172 #ifdef DEBUG
  173     static __thread int _debug_fd;
  174 #endif
  175 
  176     MallocTracer()
  177         : _lock(),
  178           _in_dlsym(false),
  179           _real_calloc(NULL),
  180           _real_malloc(NULL),
  181           _real_free(NULL),
  182           _real_realloc(NULL),
  183           _memEverRequested(0),
  184           _memCurrRequested(0) {
  185     }
  186 
  187     ~MallocTracer() {
  188         dbprintf("MallocTracer terminating...\n");
  189     }
  190 
  191     void init_all() {
  192         _in_dlsym = true;
  193 
  194         _real_calloc = (callocType *) dlsym(RTLD_NEXT, "calloc");
  195         _real_malloc = (mallocType *) dlsym(RTLD_NEXT, "malloc");
  196         _real_free = (freeType *) dlsym(RTLD_NEXT, "free");
  197         _real_realloc = (reallocType *) dlsym(RTLD_NEXT, "realloc");
  198 
  199         _in_dlsym = false;
  200 
  201         assert(_real_calloc != NULL);
  202         assert(_real_malloc != NULL);
  203         assert(_real_free != NULL);
  204         assert(_real_realloc != NULL);
  205 
  206         dbprintf("MallocTracer init ending...\n");
  207     }
  208 
  209     void trace_printf(const char * fmt, ...) {
  210 #if PRINT_TRACE
  211         if (_trace_fd == 0) {
  212             char trace_name[50];
  213             sprintf(trace_name, "malloctrace.%u.%lx", (unsigned int) getpid(), (unsigned long) pthread_self());
  214 
  215             _trace_fd = open(trace_name, O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE, S_IRUSR | S_IWUSR);
  216             if (_trace_fd <= 0) {
  217                 assert(false);
  218                 abort();
  219             }
  220         }
  221 
  222         char buf[100];
  223         size_t offset = 0;
  224 
  225 #if PRINT_TIMESTAMP
  226         unsigned long long timestamp;
  227         unsigned long * ts_low = (unsigned long *) &timestamp;
  228         unsigned long * ts_hi = ts_low + 1;
  229 
  230         asm volatile ("rdtsc" : "=a"(*ts_low), "=d"(*ts_hi));
  231         sprintf(buf, "%llx ", timestamp);
  232         offset = strlen(buf);
  233 #endif
  234 
  235         va_list ap;
  236         va_start(ap, fmt);
  237 
  238         int n = vsnprintf(buf + offset, 100, fmt, ap);
  239         if (n < 0 || n >= 100) {
  240             abort();
  241         }
  242 
  243         write(_trace_fd, buf, offset + n);
  244 #endif  // PRINT_TRACE
  245     }
  246 
  247     void dbprintf(const char * fmt, ...) {
  248 #ifdef DEBUG
  249 
  250 #if DB_PRINT_TO_FILE
  251         if (_debug_fd == 0) {
  252             char debug_name[50];
  253             sprintf(debug_name, "debuglog.%d.%lx", (unsigned int) getpid(), (unsigned long) pthread_self());
  254 
  255             _debug_fd = open(debug_name, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
  256             if (_debug_fd <= 0)
  257                 abort();
  258         }
  259 #endif
  260 
  261         char buf[BUF_SZ];
  262         va_list ap;
  263         va_start(ap, fmt);
  264 
  265         int n = vsnprintf(buf, BUF_SZ, fmt, ap);
  266         if (n < 0 || n >= BUF_SZ)
  267             abort();
  268 
  269 #if DB_PRINT_TO_FILE
  270         write(_debug_fd, buf, n);
  271 #else
  272         fprintf(stderr, "<dbprintf> %s", buf);
  273         fflush(stderr);
  274 #endif
  275 
  276 #endif  // DEBUG
  277     }
  278 
  279 };  // end of class MallocTracer
  280 
  281 __thread int MallocTracer::_trace_fd;
  282 
  283 #ifdef DEBUG
  284 __thread int MallocTracer::_debug_fd;
  285 #endif
  286 
  287 
  288 extern "C" {
  289 
  290     void * calloc(size_t nmemb, size_t size) {
  291         return MallocTracer::getMallocTracer()->calloc(nmemb, size);
  292     }
  293 
  294     void * malloc(size_t size) {
  295         return MallocTracer::getMallocTracer()->malloc(size);
  296     }
  297 
  298     void free(void * ptr) {
  299         MallocTracer::getMallocTracer()->free(ptr);
  300     }
  301 
  302     void * realloc(void * ptr, size_t size) {
  303         return MallocTracer::getMallocTracer()->realloc(ptr, size);
  304     }
  305 
  306 }
  307 
  308 #endif