Index: /trunk/psLib/src/sys/psMemory.c
===================================================================
--- /trunk/psLib/src/sys/psMemory.c	(revision 41517)
+++ /trunk/psLib/src/sys/psMemory.c	(revision 41518)
@@ -138,4 +138,7 @@
 
 }
+
+// test function : only use in test mode:
+void psMemDumpBigBlocks (psMemBlock *mb, char *mode);
 
 /******** thread safety options management ********/
@@ -589,4 +592,18 @@
 }
 
+/* these are the measured values, but below we round the ends up and down
+# define PS_BAD_MALLOC_RANGE_1_MIN 39637060
+# define PS_BAD_MALLOC_RANGE_1_MAX 39649156
+
+# define PS_BAD_MALLOC_RANGE_2_MIN 79288100
+# define PS_BAD_MALLOC_RANGE_2_MAX 79294312
+*/
+
+# define PS_BAD_MALLOC_RANGE_1_MIN 39636000
+# define PS_BAD_MALLOC_RANGE_1_MAX 39650000
+
+# define PS_BAD_MALLOC_RANGE_2_MIN 79288000
+# define PS_BAD_MALLOC_RANGE_2_MAX 79298000
+
 /* Actually allocate memory
  */
@@ -596,6 +613,12 @@
                 size_t size)
 {
-
-    psMemBlock *memBlock = malloc(sizeof(psMemBlock) + size + sizeof(void *));
+    size_t totalSize = sizeof(psMemBlock) + size + sizeof(void *);
+
+    // for gcc 4.3.2, linux 3.7.6 (at least) there are bad malloc sizes.  if a request
+    // is made for one of these bad ranges, actually allocate a larger amount 
+    if ((totalSize > PS_BAD_MALLOC_RANGE_1_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_1_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_1_MAX; }
+    if ((totalSize > PS_BAD_MALLOC_RANGE_2_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_2_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_2_MAX; }
+
+    psMemBlock *memBlock = malloc(totalSize);
     if (memBlock == NULL) {
         // this lock is only occasionally called in a given program (rarely fail malloc)
@@ -710,5 +733,5 @@
     bool blockPrinted = false;
 
-    if (memBlock == NULL) {
+    if (output && (memBlock == NULL)) {
         fprintf(output, _("NULL memory block.\n"
                           "Caught in %s at (%s:%d.).\n\n"), func, file, lineno);
@@ -717,15 +740,17 @@
     }
 
-    #if 0
+# if (0)
     // Currently psAlloc()/psRealloc() will blindly create memBlock's with a
     // size of 0.  This test is in here to check if this is really
     // happening/being use as a feature in the wild.
     if (memBlock->userMemorySize < 1) {
-        psMemBlockPrint(output, memBlock);
-        blockPrinted = true;
-        fprintf(output, _("\n\tMemory block has a size of less than 1.\n"));
-        bad = true;
-    }
-    #endif
+	bad = true;
+	if (output) {
+	    psMemBlockPrint(output, memBlock);
+	    blockPrinted = true;
+	    fprintf(output, _("\n\tMemory block has a size of less than 1.\n"));
+	}
+    }
+# endif
 
     // XXX Looking at the reference counter is subject to a race condition because this function is generally
@@ -736,59 +761,70 @@
     if (memBlock->refCounter < 1) {
         // using an unreferenced block of memory, are you?
-        psMemBlockPrint(output, memBlock);
-        blockPrinted = true;
-        fprintf(output, _("\n\tMemory block was freed but still being used.\n"));
         bad = true;
+	if (output) {
+	  psMemBlockPrint(output, memBlock);
+	  blockPrinted = true;
+	  fprintf(output, _("\n\tMemory block was freed but still being used.\n"));
+	}
     }
 
     if (memBlock->startblock != P_PS_MEMMAGIC || memBlock->endblock != P_PS_MEMMAGIC) {
-        if (!blockPrinted) {
+        bad = true;
+        if (output) {
+	  if (!blockPrinted) {
             psMemBlockPrint(output, memBlock);
             blockPrinted = true;
-        }
-        fprintf(output, _("\n\tMemory block is corrupted; buffer underflow detected.\n"));
+	  }
+	  fprintf(output, _("\n\tMemory block is corrupted; buffer underflow detected.\n"));
+	}
 	if (!checkingForCorruption) {
 	  p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false);
 	}
+    }
+
+    if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
         bad = true;
-    }
-
-    if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
-        if (!blockPrinted) {
+        if (output) {
+	  if (!blockPrinted) {
             psMemBlockPrint(output, memBlock);
             blockPrinted = true;
-        }
-        fprintf(output, _("\n\tMemory block is corrupted; buffer overflow detected.\n"));
+	  }
+	  fprintf(output, _("\n\tMemory block is corrupted; buffer overflow detected.\n"));
+	}
 	if (!checkingForCorruption) {
 	  p_psMemCheckCorruption(__FILE__, __LINE__, __func__, output, false);
 	}
-        bad = true;
-    }
-
+    }
+
+# if (0)
     //  XXX ->nextBlock, & -> prevousBlock really should not be looked at by
     //  this function as they may be changed out from underneath us by new
     //  memory allocation.  However, the memBlock itself shouldn't go away (end
     //  users responsiblity) so all we're really risking is a garbage value.
-
     //  XXX EAM : is this the error I'm catching in multithreaded processing?
     if (memBlock == memBlock->nextBlock) {
-        if (!blockPrinted) {
+        bad = true;
+	if (output) {
+	  if (!blockPrinted) {
             psMemBlockPrint(output, memBlock);
             blockPrinted = true;
-        }
-        fprintf(output, _("\n\tMemory block's ->nextBlock pointer refers to itself.\n"));
+	  }
+	  fprintf(output, _("\n\tMemory block's ->nextBlock pointer refers to itself.\n"));
+	}
+    }
+
+    if (memBlock == memBlock->previousBlock) {
         bad = true;
-    }
-
-    if (memBlock == memBlock->previousBlock) {
-        if (!blockPrinted) {
+	if (output) {
+	  if (!blockPrinted) {
             psMemBlockPrint(output, memBlock);
             blockPrinted = true;
-        }
-        fprintf(output, _("\n\tMemory block's ->previousBlock pointer refers to itself.\n"));
-        bad = true;
-    }
-
-    if (bad) {
+	  }
+	  fprintf(output, _("\n\tMemory block's ->previousBlock pointer refers to itself.\n"));
+	}
+    }
+# endif
+
+    if (bad && output) {
         fprintf(output, _("\tCaught in %s at (%s:%d).\n\n"), func, file, lineno);
     }
@@ -856,7 +892,14 @@
     bool isBlockLast = (memBlock == lastMemBlockAllocated);
 
+    size_t totalSize = sizeof(psMemBlock) + size + sizeof(void *);
+
+    // for gcc 4.3.2, linux 3.7.6 (at least) there are bad malloc sizes.  if a request
+    // is made for one of these bad ranges, actually allocate a larger amount 
+    if ((totalSize > PS_BAD_MALLOC_RANGE_1_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_1_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_1_MAX; }
+    if ((totalSize > PS_BAD_MALLOC_RANGE_2_MIN) && (totalSize < PS_BAD_MALLOC_RANGE_2_MAX)) { totalSize = PS_BAD_MALLOC_RANGE_2_MAX; }
+
     // do the expensive system call.  other threads can continue to modify other memBlocks
     // except this one and its two neighbors
-    memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(void *));
+    memBlock = (psMemBlock *)realloc(memBlock, totalSize);
     if (memBlock == NULL) {
         memBlock = memExhaustedCallback(size);
@@ -1216,5 +1259,5 @@
     #endif
 
-# if (PS_TRACE_ON)    
+# if (0 && PS_TRACE_ON)    
     // before freeing a particular block of memory, fill the entire block with FF to poison it
     // this should trigger any bad reactions early.  this may be costly, so on do it for
@@ -1333,7 +1376,6 @@
     }
 
-    // XXX shouldn't this be false?? (probably does not matter unless calling function does not 
-    // abort on error).
-    checkingForCorruption = true;
+    // revert to false after calling isBadMemBlock above
+    checkingForCorruption = false;
 
     // release the lock on the memblock list
@@ -1450,4 +1492,11 @@
 }
 
+int psMemBlockPrintPtr(FILE *output, void *ptr)
+{
+    psMemBlock *mb = (psMemBlock *)ptr - 1;
+    int status = psMemBlockPrint (stderr, mb);
+    return status;
+}
+
 bool psMemTypeEqual (void *ptr1, void *ptr2) {
 
@@ -1487,5 +1536,5 @@
     for (int i = 0; i < numLeaks; i++) {
         psMemBlock *mb = leaks[i];
-        fprintf(memFile, "%12lu\t%12zd\t%s:%d\n", mb->id, mb->userMemorySize, mb->file, mb->lineno);
+        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);
         total += mb->userMemorySize;
     }
@@ -1497,2 +1546,19 @@
     num++;
 }
+
+static FILE *memDumpFile = NULL;
+
+void psMemDumpBigBlocks (psMemBlock *mb, char *mode) {
+
+    if (!memDumpFile) {
+	memDumpFile = fopen ("memdump.txt", "w");
+	psAssert (memDumpFile, "failed to open memdump.txt");
+    }
+
+    if (mb->userMemorySize < 1) return;
+    // 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);
+    fprintf (memDumpFile, "--- %s ---\n", mode);
+    psMemBlockPrint (memDumpFile, mb);
+    fprintf (memDumpFile, "-----------\n");
+    return;
+}
Index: /trunk/psLib/src/sys/psMemory.h
===================================================================
--- /trunk/psLib/src/sys/psMemory.h	(revision 41517)
+++ /trunk/psLib/src/sys/psMemory.h	(revision 41518)
@@ -651,4 +651,15 @@
 );
 
+/** print detailed information about a pointer allocated by psAlloc
+ *
+ * This function prints a detailed description of a psMemBlock to output.
+ *
+ * @return the return status of fprintf()
+ */
+int psMemBlockPrintPtr(
+    FILE *output,                       ///< FILE to write information too
+    void *ptr ///< pointer to be examined
+);
+
 /** test for matching types (equal free functions)
  *
