Changeset 41518
- Timestamp:
- Apr 2, 2021, 2:11:05 PM (5 years ago)
- Location:
- trunk/psLib/src/sys
- Files:
-
- 2 edited
-
psMemory.c (modified) (12 diffs)
-
psMemory.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMemory.c
r41506 r41518 138 138 139 139 } 140 141 // test function : only use in test mode: 142 void psMemDumpBigBlocks (psMemBlock *mb, char *mode); 140 143 141 144 /******** thread safety options management ********/ … … 589 592 } 590 593 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 591 608 /* Actually allocate memory 592 609 */ … … 596 613 size_t size) 597 614 { 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); 600 623 if (memBlock == NULL) { 601 624 // this lock is only occasionally called in a given program (rarely fail malloc) … … 710 733 bool blockPrinted = false; 711 734 712 if ( memBlock == NULL) {735 if (output && (memBlock == NULL)) { 713 736 fprintf(output, _("NULL memory block.\n" 714 737 "Caught in %s at (%s:%d.).\n\n"), func, file, lineno); … … 717 740 } 718 741 719 #if 0 742 # if (0) 720 743 // Currently psAlloc()/psRealloc() will blindly create memBlock's with a 721 744 // size of 0. This test is in here to check if this is really 722 745 // happening/being use as a feature in the wild. 723 746 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 730 755 731 756 // XXX Looking at the reference counter is subject to a race condition because this function is generally … … 736 761 if (memBlock->refCounter < 1) { 737 762 // 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"));741 763 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 } 742 769 } 743 770 744 771 if (memBlock->startblock != P_PS_MEMMAGIC || memBlock->endblock != P_PS_MEMMAGIC) { 745 if (!blockPrinted) { 772 bad = true; 773 if (output) { 774 if (!blockPrinted) { 746 775 psMemBlockPrint(output, memBlock); 747 776 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 } 750 780 if (!checkingForCorruption) { 751 781 p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false); 752 782 } 783 } 784 785 if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) { 753 786 bad = true; 754 } 755 756 if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) { 757 if (!blockPrinted) { 787 if (output) { 788 if (!blockPrinted) { 758 789 psMemBlockPrint(output, memBlock); 759 790 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 } 762 794 if (!checkingForCorruption) { 763 795 p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false); 764 796 } 765 bad = true;766 } 767 797 } 798 799 # if (0) 768 800 // XXX ->nextBlock, & -> prevousBlock really should not be looked at by 769 801 // this function as they may be changed out from underneath us by new 770 802 // memory allocation. However, the memBlock itself shouldn't go away (end 771 803 // users responsiblity) so all we're really risking is a garbage value. 772 773 804 // XXX EAM : is this the error I'm catching in multithreaded processing? 774 805 if (memBlock == memBlock->nextBlock) { 775 if (!blockPrinted) { 806 bad = true; 807 if (output) { 808 if (!blockPrinted) { 776 809 psMemBlockPrint(output, memBlock); 777 810 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) { 780 817 bad = true; 781 } 782 783 if (memBlock == memBlock->previousBlock) { 784 if (!blockPrinted) { 818 if (output) { 819 if (!blockPrinted) { 785 820 psMemBlockPrint(output, memBlock); 786 821 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) { 793 829 fprintf(output, _("\tCaught in %s at (%s:%d).\n\n"), func, file, lineno); 794 830 } … … 856 892 bool isBlockLast = (memBlock == lastMemBlockAllocated); 857 893 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 858 901 // do the expensive system call. other threads can continue to modify other memBlocks 859 902 // except this one and its two neighbors 860 memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(void *));903 memBlock = (psMemBlock *)realloc(memBlock, totalSize); 861 904 if (memBlock == NULL) { 862 905 memBlock = memExhaustedCallback(size); … … 1216 1259 #endif 1217 1260 1218 # if ( PS_TRACE_ON)1261 # if (0 && PS_TRACE_ON) 1219 1262 // before freeing a particular block of memory, fill the entire block with FF to poison it 1220 1263 // this should trigger any bad reactions early. this may be costly, so on do it for … … 1333 1376 } 1334 1377 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; 1338 1380 1339 1381 // release the lock on the memblock list … … 1450 1492 } 1451 1493 1494 int psMemBlockPrintPtr(FILE *output, void *ptr) 1495 { 1496 psMemBlock *mb = (psMemBlock *)ptr - 1; 1497 int status = psMemBlockPrint (stderr, mb); 1498 return status; 1499 } 1500 1452 1501 bool psMemTypeEqual (void *ptr1, void *ptr2) { 1453 1502 … … 1487 1536 for (int i = 0; i < numLeaks; i++) { 1488 1537 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); 1490 1539 total += mb->userMemorySize; 1491 1540 } … … 1497 1546 num++; 1498 1547 } 1548 1549 static FILE *memDumpFile = NULL; 1550 1551 void 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 651 651 ); 652 652 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 */ 659 int psMemBlockPrintPtr( 660 FILE *output, ///< FILE to write information too 661 void *ptr ///< pointer to be examined 662 ); 663 653 664 /** test for matching types (equal free functions) 654 665 *
Note:
See TracChangeset
for help on using the changeset viewer.
