IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41518


Ignore:
Timestamp:
Apr 2, 2021, 2:11:05 PM (5 years ago)
Author:
eugene
Message:

add fixes to avoid bad memory ranges (needed for at least for gentoo kernel 3.7.6, gcc version 4.3.2-r3); do not print if output file is not defined; add some test functions to help in memory debugging

Location:
trunk/psLib/src/sys
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sys/psMemory.c

    r41506 r41518  
    138138
    139139}
     140
     141// test function : only use in test mode:
     142void psMemDumpBigBlocks (psMemBlock *mb, char *mode);
    140143
    141144/******** thread safety options management ********/
     
    589592}
    590593
     594/* these are the measured values, but below we round the ends up and down
     595# define PS_BAD_MALLOC_RANGE_1_MIN 39637060
     596# define PS_BAD_MALLOC_RANGE_1_MAX 39649156
     597
     598# define PS_BAD_MALLOC_RANGE_2_MIN 79288100
     599# define PS_BAD_MALLOC_RANGE_2_MAX 79294312
     600*/
     601
     602# define PS_BAD_MALLOC_RANGE_1_MIN 39636000
     603# define PS_BAD_MALLOC_RANGE_1_MAX 39650000
     604
     605# define PS_BAD_MALLOC_RANGE_2_MIN 79288000
     606# define PS_BAD_MALLOC_RANGE_2_MAX 79298000
     607
    591608/* Actually allocate memory
    592609 */
     
    596613                size_t size)
    597614{
    598 
    599     psMemBlock *memBlock = malloc(sizeof(psMemBlock) + size + sizeof(void *));
     615    size_t totalSize = sizeof(psMemBlock) + size + sizeof(void *);
     616
     617    // for gcc 4.3.2, linux 3.7.6 (at least) there are bad malloc sizes.  if a request
     618    // is made for one of these bad ranges, actually allocate a larger amount
     619    if ((totalSize > PS_BAD_MALLOC_RANGE_1_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_1_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_1_MAX; }
     620    if ((totalSize > PS_BAD_MALLOC_RANGE_2_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_2_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_2_MAX; }
     621
     622    psMemBlock *memBlock = malloc(totalSize);
    600623    if (memBlock == NULL) {
    601624        // this lock is only occasionally called in a given program (rarely fail malloc)
     
    710733    bool blockPrinted = false;
    711734
    712     if (memBlock == NULL) {
     735    if (output && (memBlock == NULL)) {
    713736        fprintf(output, _("NULL memory block.\n"
    714737                          "Caught in %s at (%s:%d.).\n\n"), func, file, lineno);
     
    717740    }
    718741
    719     #if 0
     742# if (0)
    720743    // Currently psAlloc()/psRealloc() will blindly create memBlock's with a
    721744    // size of 0.  This test is in here to check if this is really
    722745    // happening/being use as a feature in the wild.
    723746    if (memBlock->userMemorySize < 1) {
    724         psMemBlockPrint(output, memBlock);
    725         blockPrinted = true;
    726         fprintf(output, _("\n\tMemory block has a size of less than 1.\n"));
    727         bad = true;
    728     }
    729     #endif
     747        bad = true;
     748        if (output) {
     749            psMemBlockPrint(output, memBlock);
     750            blockPrinted = true;
     751            fprintf(output, _("\n\tMemory block has a size of less than 1.\n"));
     752        }
     753    }
     754# endif
    730755
    731756    // XXX Looking at the reference counter is subject to a race condition because this function is generally
     
    736761    if (memBlock->refCounter < 1) {
    737762        // using an unreferenced block of memory, are you?
    738         psMemBlockPrint(output, memBlock);
    739         blockPrinted = true;
    740         fprintf(output, _("\n\tMemory block was freed but still being used.\n"));
    741763        bad = true;
     764        if (output) {
     765          psMemBlockPrint(output, memBlock);
     766          blockPrinted = true;
     767          fprintf(output, _("\n\tMemory block was freed but still being used.\n"));
     768        }
    742769    }
    743770
    744771    if (memBlock->startblock != P_PS_MEMMAGIC || memBlock->endblock != P_PS_MEMMAGIC) {
    745         if (!blockPrinted) {
     772        bad = true;
     773        if (output) {
     774          if (!blockPrinted) {
    746775            psMemBlockPrint(output, memBlock);
    747776            blockPrinted = true;
    748         }
    749         fprintf(output, _("\n\tMemory block is corrupted; buffer underflow detected.\n"));
     777          }
     778          fprintf(output, _("\n\tMemory block is corrupted; buffer underflow detected.\n"));
     779        }
    750780        if (!checkingForCorruption) {
    751781          p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false);
    752782        }
     783    }
     784
     785    if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
    753786        bad = true;
    754     }
    755 
    756     if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
    757         if (!blockPrinted) {
     787        if (output) {
     788          if (!blockPrinted) {
    758789            psMemBlockPrint(output, memBlock);
    759790            blockPrinted = true;
    760         }
    761         fprintf(output, _("\n\tMemory block is corrupted; buffer overflow detected.\n"));
     791          }
     792          fprintf(output, _("\n\tMemory block is corrupted; buffer overflow detected.\n"));
     793        }
    762794        if (!checkingForCorruption) {
    763795          p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false);
    764796        }
    765         bad = true;
    766     }
    767 
     797    }
     798
     799# if (0)
    768800    //  XXX ->nextBlock, & -> prevousBlock really should not be looked at by
    769801    //  this function as they may be changed out from underneath us by new
    770802    //  memory allocation.  However, the memBlock itself shouldn't go away (end
    771803    //  users responsiblity) so all we're really risking is a garbage value.
    772 
    773804    //  XXX EAM : is this the error I'm catching in multithreaded processing?
    774805    if (memBlock == memBlock->nextBlock) {
    775         if (!blockPrinted) {
     806        bad = true;
     807        if (output) {
     808          if (!blockPrinted) {
    776809            psMemBlockPrint(output, memBlock);
    777810            blockPrinted = true;
    778         }
    779         fprintf(output, _("\n\tMemory block's ->nextBlock pointer refers to itself.\n"));
     811          }
     812          fprintf(output, _("\n\tMemory block's ->nextBlock pointer refers to itself.\n"));
     813        }
     814    }
     815
     816    if (memBlock == memBlock->previousBlock) {
    780817        bad = true;
    781     }
    782 
    783     if (memBlock == memBlock->previousBlock) {
    784         if (!blockPrinted) {
     818        if (output) {
     819          if (!blockPrinted) {
    785820            psMemBlockPrint(output, memBlock);
    786821            blockPrinted = true;
    787         }
    788         fprintf(output, _("\n\tMemory block's ->previousBlock pointer refers to itself.\n"));
    789         bad = true;
    790     }
    791 
    792     if (bad) {
     822          }
     823          fprintf(output, _("\n\tMemory block's ->previousBlock pointer refers to itself.\n"));
     824        }
     825    }
     826# endif
     827
     828    if (bad && output) {
    793829        fprintf(output, _("\tCaught in %s at (%s:%d).\n\n"), func, file, lineno);
    794830    }
     
    856892    bool isBlockLast = (memBlock == lastMemBlockAllocated);
    857893
     894    size_t totalSize = sizeof(psMemBlock) + size + sizeof(void *);
     895
     896    // for gcc 4.3.2, linux 3.7.6 (at least) there are bad malloc sizes.  if a request
     897    // is made for one of these bad ranges, actually allocate a larger amount
     898    if ((totalSize > PS_BAD_MALLOC_RANGE_1_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_1_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_1_MAX; }
     899    if ((totalSize > PS_BAD_MALLOC_RANGE_2_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_2_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_2_MAX; }
     900
    858901    // do the expensive system call.  other threads can continue to modify other memBlocks
    859902    // except this one and its two neighbors
    860     memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(void *));
     903    memBlock = (psMemBlock *)realloc(memBlock, totalSize);
    861904    if (memBlock == NULL) {
    862905        memBlock = memExhaustedCallback(size);
     
    12161259    #endif
    12171260
    1218 # if (PS_TRACE_ON)   
     1261# if (0 && PS_TRACE_ON)   
    12191262    // before freeing a particular block of memory, fill the entire block with FF to poison it
    12201263    // this should trigger any bad reactions early.  this may be costly, so on do it for
     
    13331376    }
    13341377
    1335     // XXX shouldn't this be false?? (probably does not matter unless calling function does not
    1336     // abort on error).
    1337     checkingForCorruption = true;
     1378    // revert to false after calling isBadMemBlock above
     1379    checkingForCorruption = false;
    13381380
    13391381    // release the lock on the memblock list
     
    14501492}
    14511493
     1494int psMemBlockPrintPtr(FILE *output, void *ptr)
     1495{
     1496    psMemBlock *mb = (psMemBlock *)ptr - 1;
     1497    int status = psMemBlockPrint (stderr, mb);
     1498    return status;
     1499}
     1500
    14521501bool psMemTypeEqual (void *ptr1, void *ptr2) {
    14531502
     
    14871536    for (int i = 0; i < numLeaks; i++) {
    14881537        psMemBlock *mb = leaks[i];
    1489         fprintf(memFile, "%12lu\t%12zd\t%s:%d\n", mb->id, mb->userMemorySize, mb->file, mb->lineno);
     1538        fprintf(memFile, "%12lu\t%12zd\t%p\t%p\t%s:%d\n", mb->id, mb->userMemorySize, (mb + 1), (char *) (mb + 1) + mb->userMemorySize, mb->file, mb->lineno);
    14901539        total += mb->userMemorySize;
    14911540    }
     
    14971546    num++;
    14981547}
     1548
     1549static FILE *memDumpFile = NULL;
     1550
     1551void psMemDumpBigBlocks (psMemBlock *mb, char *mode) {
     1552
     1553    if (!memDumpFile) {
     1554        memDumpFile = fopen ("memdump.txt", "w");
     1555        psAssert (memDumpFile, "failed to open memdump.txt");
     1556    }
     1557
     1558    if (mb->userMemorySize < 1) return;
     1559    // fprintf(memDumpFile, "%12lu %12zd %16p %16p %8s %s:%d\n", mb->id, mb->userMemorySize, (mb + 1), (char *) (mb + 1) + mb->userMemorySize, mode, mb->file, mb->lineno);
     1560    fprintf (memDumpFile, "--- %s ---\n", mode);
     1561    psMemBlockPrint (memDumpFile, mb);
     1562    fprintf (memDumpFile, "-----------\n");
     1563    return;
     1564}
  • trunk/psLib/src/sys/psMemory.h

    r32174 r41518  
    651651);
    652652
     653/** print detailed information about a pointer allocated by psAlloc
     654 *
     655 * This function prints a detailed description of a psMemBlock to output.
     656 *
     657 * @return the return status of fprintf()
     658 */
     659int psMemBlockPrintPtr(
     660    FILE *output,                       ///< FILE to write information too
     661    void *ptr ///< pointer to be examined
     662);
     663
    653664/** test for matching types (equal free functions)
    654665 *
Note: See TracChangeset for help on using the changeset viewer.