IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 9, 2007, 12:23:05 PM (19 years ago)
Author:
jhoblitt
Message:

add memory backtracing support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/jch-memory/psLib/src/sys/psMemory.c

    r10940 r10998  
    1010*  @author Joshua Hoblitt, University of Hawaii
    1111*
    12 *  @version $Revision: 1.88.2.21 $ $Name: not supported by cvs2svn $
    13 *  @date $Date: 2007-01-05 21:26:52 $
     12*  @version $Revision: 1.88.2.22 $ $Name: not supported by cvs2svn $
     13*  @date $Date: 2007-01-09 22:23:05 $
    1414*
    1515*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1616*/
     17
     18#if HAVE_CONFIG_H
     19# include <config.h>
     20#endif
    1721
    1822#define PS_ALLOW_MALLOC                    // we're allowed to call malloc()
     
    2327#include <string.h>
    2428#include <assert.h>
     29
     30#if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
     31# include <execinfo.h>
     32#endif
    2533
    2634#include "psMemory.h"
     
    424432    memBlock->func = func;
    425433
     434    #if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
     435    #define BACKTRACE_BUFFER_SIZE 32
     436    // psMemBlock.func is a 'const char *', so basically we're going to abuse
     437    // that and treat it as a void ** to carry around backtrace information.
     438    // psMemBlock is not ifdef'd to make sure that psMemBlock is always the
     439    // same size & layout reguardless of the pslib .so that's being linked
     440    // against
     441    void **bt = malloc(BACKTRACE_BUFFER_SIZE * sizeof(void *));
     442    if (bt == NULL) {
     443        PS_MEM_ABORT(__func__, "Failed to allocate memmory for backtrace buffer: %zd bytes at %s (%s:%d)", 32 * sizeof(void *), func, file, lineno);
     444    }
     445    *(size_t *)&memBlock->backtraceSize = backtrace(bt, BACKTRACE_BUFFER_SIZE);
     446    *(void ***)&memBlock->backtrace = bt;
     447    #endif // ifdef HAVE_BACKTRACE
     448
    426449    // free function
    427450    memBlock->freeFunc = NULL;
     
    548571    MUTEX_LOCK(&memBlockListMutex);
    549572
    550     for (psMemBlock *memBlock = topBlock; memBlock != NULL; memBlock = memBlock->nextBlock) {
     573    // find the very first memblock
     574    psMemBlock *memBlock = NULL;
     575    for (memBlock = topBlock; memBlock->nextBlock != NULL; memBlock = memBlock->nextBlock) { }
     576
     577    // iterate through the block list starting with the oldest block
     578    for (; memBlock != NULL; memBlock = memBlock->previousBlock) {
    551579        if ( (memBlock->refCounter > 0) &&
    552580                ( (persistence) || (!persistence && !memBlock->persistent) ) &&
     
    557585            if (fd != NULL) {
    558586                if (nleak == 1) {
    559                     fprintf(fd, "   %20s:line ID\n", "file");
     587                    fprintf(fd, "# func at (file:line)  ID: X\n");
    560588                }
    561589
    562                 fprintf(fd, "   %20s:%-4d %lu\n", memBlock->file, (int)memBlock->lineno, (unsigned long)memBlock->id);
     590                fprintf(fd, "%s at (%s:%d)  ID: %lu", memBlock->func, memBlock->file, (int)memBlock->lineno, (unsigned long)memBlock->id);
     591                #if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
     592
     593                size_t size = memBlock->backtraceSize;
     594                char **strings = backtrace_symbols((void *const *)memBlock->backtrace, size);
     595
     596                fprintf(fd, "  Alloc Call Depth: %zd\n", size);
     597
     598                for (int i = 0; i < size; i++) {
     599                    // always ident
     600                    int ident = 4;  // initial indent
     601                    ident += 2 * i; // nesting depth
     602                    fprintf(fd, "%*s", ident, "");
     603
     604                    // if the caller was an anon function then strchr won't
     605                    // find a '(' in the string and will return NULL
     606                    char *caller = caller = strchr(strings[i], '(');
     607                    if (caller) {
     608                        // skip over the '('
     609                        caller++;
     610                        // find the end of the symbol name
     611                        size_t callerLength = abs(strchr(caller, '+') - caller);
     612                        // print just the symbol name
     613                        for (int i = 0; i < callerLength; i++) {
     614                            fputc(caller[i],fd);
     615                        }
     616                        fprintf(fd, "\n");
     617                    } else {
     618                        fprintf(fd, "(unknown)\n");
     619                    }
     620                }
     621
     622                free (strings);
     623                #else // ifdef HAVE_BACKTRACE
     624                // \n after "Memory Block ID"
     625                fprintf(fd, "\n");
     626                #endif // ifdef HAVE_BACKTRACE
     627
    563628            }
    564629        }
Note: See TracChangeset for help on using the changeset viewer.