IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 264


Ignore:
Timestamp:
Mar 19, 2004, 9:13:42 AM (22 years ago)
Author:
rhl
Message:

1/ Use PS_ALLOW_MALLOC to enable calling malloc()
2/ Don't limit ourselves to NMEMBLOCK allocations -- but this is still a
poor implementation!
3/ Add and use memFreeCB0()
4/ Move test code to tst_memory.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/archive/pslib/src/Utils/memory.c

    r227 r264  
    22#include <stdio.h>
    33#include <assert.h>
     4#define PS_ALLOW_MALLOC                 // we're allowed to call malloc()
    45#include "psUtils.h"
    56#include "Private/p_psMemory.h"
    6 
    7 #undef malloc                           // _We_ are allowed to call these
    8 #undef realloc
    9 #undef free
    107
    118#undef psAlloc                          // don't get the __FILE__ versions
     
    1512static int bad_memblock(const psMemBlock *m, int quiet);
    1613/*
    17  * This strawman allocation package only handles up to NMEMBLOCK allocations
    18  */
    19 #define NMEMBLOCK 10000                 // max. number of calls to psAlloc
    20 static psMemBlock *memBlocks[NMEMBLOCK];
     14 * This strawman allocation package uses an array to track calls to psAlloc;
     15 * not nearly good enough for production work!
     16 */
     17static int nMemBlock = 0;               // size of memBlocks
     18static psMemBlock **memBlocks = NULL;
    2119
    2220/*****************************************************************************/
     
    7775        }
    7876        fprintf(stderr, "\n");
    79     } else if(ptr->refCounter <= 0) {
     77    } else if (ptr->refCounter <= 0) {
    8078        psError(__func__, "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
    8179                ptr->id, ptr->file, ptr->lineno, file, lineno);
    82     } else if(ptr->refCounter > 1) {
     80    } else if (ptr->refCounter > 1) {
    8381        psError(__func__, "Block %ld allocated at %s:%d freed while still referenced at %s:%d\n",
    8482                ptr->id, ptr->file, ptr->lineno, file, lineno);
     
    138136}
    139137
     138static int memFreeCB0(const psMemBlock *ptr)
     139{
     140    static int incr = 0;                // "p_psMemFreeID += incr"
     141
     142    assert (ptr != NULL);               // prevent compiler warnings
     143   
     144    return incr;
     145}
     146
    140147/*
    141148 * The default callbacks, and the routines to change them
    142149 */
    143150static psMemCallback memAllocateCB = memAllocateCB0;
    144 static psMemCallback memFreeCB = memAllocateCB0;
     151static psMemCallback memFreeCB = memFreeCB0;
    145152
    146153psMemCallback psMemAllocateSetCB(psMemCallback func)
     
    157164    psMemCallback old = memFreeCB;
    158165
    159     memFreeCB = (func != NULL) ? func : memAllocateCB0;
     166    memFreeCB = (func != NULL) ? func : memFreeCB0;
    160167
    161168    return old;
     
    183190             int quiet)                 // be quiet?
    184191{
    185     if(m == NULL) {
     192    if (m == NULL) {
    186193        if (!quiet) {
    187194            psError(__func__, "psMemCheckCorruption: NULL memory block\n");
     
    190197    }
    191198   
    192     if(!ALIGNED(m)) {
     199    if (!ALIGNED(m)) {
    193200        if (!quiet) {
    194201            psError(__func__, "psMemCheckCorruption: non-aligned memory block\n");
     
    197204    }
    198205   
    199     if(m->magic0 != P_PS_MEMMAGIC || m->magic != P_PS_MEMMAGIC) {
     206    if (m->magic0 != P_PS_MEMMAGIC || m->magic != P_PS_MEMMAGIC) {
    200207        if (!quiet) {
    201208            psError(__func__,
     
    211218{
    212219    int nbad = 0;                       // number of bad blocks
     220
     221    if (memBlocks == NULL) {
     222        return 0;                       // no memory is allocated to be corrupted
     223    }
    213224
    214225    for (int i = 1; i <= memid; i++) {
     
    252263     * Did the user ask to be informed about this allocation?
    253264     */
    254     if(ptr->id == p_psMemAllocateID) {
     265   
     266    if (ptr->id == p_psMemAllocateID && p_psMemAllocateID > 0) {
    255267        p_psMemAllocateID += memAllocateCB(ptr);       
    256268    }
    257269    /*
    258      * Register the allocation.  This is not production quality!
     270     * Register the allocation.  This is not a production quality algorithm!
    259271     */
    260     if (memid == NMEMBLOCK) {
    261         psAbort(__func__, "I'm sorry, but I can only handle %d allocations",
    262                 NMEMBLOCK);
     272    if (memid >= nMemBlock) {
     273        nMemBlock = (nMemBlock == 0) ? 10000 : 2*nMemBlock;
     274        memBlocks = realloc(memBlocks, nMemBlock*sizeof(psMemBlock *)); // NOT psRealloc
    263275    }
    264276    memBlocks[ptr->id] = ptr;
     
    292304     * Did the user ask to be informed about this deallocation?
    293305     */
    294     if (ptr->id == p_psMemFreeID) {
     306    if (ptr->id == p_psMemFreeID && p_psMemFreeID > 0) {
    295307        p_psMemFreeID += memFreeCB(ptr);       
    296308    }
     
    303315        }
    304316        ptr->refCounter--;
     317#if 1
    305318        memBlocks[ptr->id] = NULL;      // XXX sub-optimal! Can't check
    306                                         // freed blocks for corruption
     319                                        // freed blocks for corruption/double frees
    307320        free(ptr);
     321#endif
    308322    }
    309323}
     
    320334{
    321335    int nleak = 0;
    322    
     336
     337    if (memBlocks == NULL) {            // nothing was allocated
     338        return 0;
     339    }
     340
    323341    for (int i = id0; i <= memid; i++) {
    324342        if (memBlocks[i] != NULL) {
     
    408426    return vptr;
    409427}
    410 
    411 /*****************************************************************************/
    412 #if 0                                   // Testing
    413 #include <signal.h>
    414 /*
    415  * These are usually defined in psMemory.h, but in this file (only!)
    416  * they are undefined explicitly, so let's get them back
    417  */
    418 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
    419 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
    420 #define psFree(size) p_psFree(size, __FILE__, __LINE__)
    421 
    422 /*****************************************************************************/
    423 /*
    424  * My callbacks
    425  */
    426 static int my_MemAllocateCB(const psMemBlock *ptr)
    427 {
    428     static int incr = 0;                // "p_psMemAllocateID += incr"
    429 
    430     assert (ptr != NULL);               // prevent compiler warnings
    431    
    432     fprintf(stderr, "Allocating block %ld (%s:%d)\n",
    433             ptr->id, ptr->file, ptr->lineno);
    434    
    435     incr = 2;                           // See every other allocation
    436 
    437     return incr;
    438 }
    439 
    440 static void *my_MemExhaustedCB(size_t size)
    441 {
    442     psError(__func__, "Bye bye sweet world\n");
    443    
    444     return NULL;
    445 }
    446 
    447 static psMemProblemCallback default_MemProblemCB = NULL;
    448 
    449 static void my_MemProblemCB(const psMemBlock *ptr,
    450                             const char *file, int lineno)
    451 {
    452     fprintf(stderr, "I foresee trouble:\n");
    453 
    454     default_MemProblemCB(ptr, file, lineno);
    455 }
    456    
    457 /*****************************************************************************/
    458 
    459 int main(void)
    460 {
    461     /*
    462      * Survive any aborts that are generated
    463      * This doesn't seem to work on mac os/x 10.2.8
    464      */
    465     if (signal(SIGABRT, SIG_IGN) == SIG_ERR) {
    466         perror("Installing a SIGABRT handler");
    467     }
    468     /*
    469      * Install my callbacks
    470      */
    471     (void)psMemAllocateSetCB(my_MemAllocateCB);
    472     default_MemProblemCB = psMemProblemSetCB(my_MemProblemCB);
    473     (void)psMemExhaustedSetCB(my_MemExhaustedCB);
    474     /*
    475      * Request callback on first allocation
    476      */
    477     (void)psMemSetAllocateID(1);
    478     /*
    479      * Start allocating
    480      */
    481     char *str = psAlloc(10);
    482     double *x = psAlloc(1);
    483     int *i = psAlloc(1);
    484     *i = 1;
    485     *x = 1.234;
    486 
    487     psFree(i);
    488    
    489     str = psRealloc(str, 20);
    490     psFree(str);
    491 #if 1
    492     /*
    493      * An illegal double-free
    494      */
    495     psFree(str);
    496 #endif
    497 
    498 #if 1
    499     /*
    500      * Free memory not allocated with psAlloc
    501      */
    502     psFree(malloc(1));
    503 #endif
    504 
    505 #if 0
    506     /*
    507      * Ask for more memory than we can get
    508      */
    509     psAlloc((size_t)-1 - sizeof(psMemBlock));
    510 #endif
    511 
    512 #if 0
    513     /*
    514      * Increment refCounter on non-malloced pointer
    515      */
    516     psMemGetRefCounter(malloc(1));
    517 #endif
    518 
    519 #if 0
    520     /*
    521      * Mess with the refCounter
    522      */
    523     (void)psMemIncrRefCounter(x);
    524     (void)psMemIncrRefCounter(x);
    525     (void)psMemDecrRefCounter(x);       // now == 2
    526 #endif
    527 
    528 #if 0
    529     /*
    530      * A memory leak
    531      */
    532     {
    533         char *str2 = psAlloc(20);
    534        
    535         sprintf(str2, "XXX");
    536     }
    537 #else
    538     psFree(x);
    539 #endif
    540 
    541 #if 1
    542     /*
    543      * Corrupt some memory
    544      */
    545     char *c = psAlloc(1);
    546     c[-4] = 0;
    547 #endif
    548 
    549     /*************************************************************************/
    550     /*
    551      * Check for memory corruption
    552      */
    553     if(psMemCheckCorruption(1)) {
    554         psError(__func__, "Detected corrupted memory\n\n");
    555     }
    556     /*
    557      * Check for memory leaks
    558      */
    559     psMemBlock **leaks = NULL;
    560     int nleak = psMemCheckLeaks(0, &leaks, NULL);
    561 
    562     if (nleak > 0) {
    563         fprintf(stderr, "Memory is leaking (%d blocks):\n", nleak);
    564         fprintf(stderr, "   %20s:line ID\n", "file");
    565         for (int i = 0; i < nleak; i++) {
    566             fprintf(stderr, "   %20s:%-4d %ld\n",
    567                     leaks[i]->file, leaks[i]->lineno, leaks[i]->id);
    568         }
    569         psFree(leaks);
    570     }
    571 
    572     if ((nleak = psMemCheckLeaks(0, NULL, NULL)) > 0) {
    573         fprintf(stderr, "Memory is still leaking (%d blocks):\n", nleak);
    574         psMemCheckLeaks(0, NULL, stderr);
    575     }
    576 
    577     return 0;
    578 }
    579 #endif
Note: See TracChangeset for help on using the changeset viewer.