Exemple #1
0
void *
mem_realloc_ (
    void       *client_ptr,             /*  Block of memory to reallocate    */
    size_t      size,                   /*  Desired size of memory block     */
    const char *filename,               /*  Name of source file making call  */
    word        lineno                  /*  Line number in calling source    */
)
{
    MEMHDR
        *ptr,
        *next;

    ASSERT (client_ptr);
    ASSERT (size > 0);

    /*  Check that block is valid                                            */
    ptr = CLIENT_2_HDR (client_ptr);
    if (ptr-> tag != MEMTAG)
        mem_tag_err (ptr, filename, lineno);

    /*  Invalidate header                                                    */
    ptr-> tag = MEMUNTAG;

    mem_total -= ptr-> size;
    mem_free_count += 1;

    
    next = ptr-> next;                  /*  Save where we were linked        */
    list_unlink (ptr);                  /*     and unlink                    */
    
    /*  Reallocate memory block                                              */
    ptr = (MEMHDR *) realloc (ptr, RESERVE_SIZE + size);
    if (ptr == NULL)                    /*  If nothing free, do a hunt       */
      {                                 /*    and try again...               */
        mem_scavenge ();
        ptr = (MEMHDR *) realloc (ptr, RESERVE_SIZE + size);
        if (ptr == NULL)
            return (NULL);              /*  Really in trouble now!           */
      }

#   if (defined (MEM_TRACE))
    if (filename)
        trace ("%s (%d): realloc %d bytes ->%p", filename, lineno, size, ptr);
#   endif

    /*  Update header                                                        */
    ptr-> tag  = MEMTAG;
    ptr-> size = size;
    ptr-> file = filename;
    ptr-> line = lineno;

    list_reset (ptr);                   /*  Set up block as list             */
    list_relink_before (ptr, next);     /*  And link where old block was     */

    mem_total += size;                  /*  Keep count of space used         */
    mem_alloc_count += 1;               /*    and number of allocations      */

    return (HDR_2_CLIENT (ptr));
}
Exemple #2
0
/*
 *  MEMDBG_alloc
 *  Allocate a memory block. makes a protected call to malloc(), allocating
 *  extra data, and adding data to all required structures.
 */
void * MEMDBG_alloc(size_t size, char *file, int line)
{
	MEMDBG_HDR      *p;

	if ( ((signed long long)mem_size) < 0)
		fprintf(stderr, "MEMDBG_alloc %lld %s:%d  mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);

	p = (MEMDBG_HDR*)malloc(RESERVE_SZ + size + 4);
#ifdef MEMDBG_EXTRA_CHECKS
#ifdef _OPENMP
	{
		int i = 0;
		do {
#pragma omp critical (memdbg_crit)
			{
				if (!p && freed_mem_size > (RESERVE_SZ + size + 4) && !p && freed_cnt)
					i = 1;
			}
			if (i) {
				release_oldest_freed_block();
				p = (MEMDBG_HDR*)malloc(RESERVE_SZ + size + 4);
			}
		} while (i && !p);
	}
#else
	/* this is the 'right' block, but hard to do with the restrictions of no branching out that omp critical places on us */
	if (!p && freed_mem_size > (RESERVE_SZ + size + 4)) {
		while (!p && freed_cnt) {
			release_oldest_freed_block();
			p = (MEMDBG_HDR*)malloc(RESERVE_SZ + size + 4);
		}
	}
#endif
#endif
	if (!p) {
		if ( ((signed long long)mem_size) < 0)
			fprintf(stderr, "MEMDBG_alloc (end) %lld %s:%d  mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);
		return NULL;
	}
	p->mdbg_fpst = MEMFPOST;
	p->mdbg_size = size;
	p->mdbg_file = file;
	p->mdbg_line = line;
	p->mdbg_hdr2 = (MEMDBG_HDR2*)(((char*)p)+RESERVE_SZ + size);
	memcpy(p->mdbg_hdr2, cpMEMFPOST, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
	{
		p->mdbg_cnt = ++alloc_cnt;
		mem_size += size;
		if (mem_size > max_mem_size)
			max_mem_size = mem_size;
		MEMDBG_LIST_add(p);
	}
	if ( ((signed long long)mem_size) < 0)
		fprintf(stderr, "MEMDBG_alloc (end) %lld %s:%d  mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);
	return HDR_2_CLIENT(p);
}
Exemple #3
0
void *
xmlMallocAtomicLoc(size_t size, const char * file, int line)
{
  MEMHDR *p;
  void *ret;

  if (!xmlMemInitialized) xmlInitMemory();
#ifdef DEBUG_MEMORY
  xmlGenericError(xmlGenericErrorContext,
                  "Malloc(%d)\n",size);
#endif

  TEST_POINT

  p = (MEMHDR *) malloc(RESERVE_SIZE+size);

  if (!p)
  {
    xmlGenericError(xmlGenericErrorContext,
                    "xmlMallocLoc : Out of free space\n");
    xmlMemoryDump();
    return(NULL);
  }
  p->mh_tag = MEMTAG;
  p->mh_size = size;
  p->mh_type = MALLOC_ATOMIC_TYPE;
  p->mh_file = file;
  p->mh_line = line;
  xmlMutexLock(xmlMemMutex);
  p->mh_number = ++block;
  debugMemSize += size;
  debugMemBlocks++;
  if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
  debugmem_list_add(p);
#endif
  xmlMutexUnlock(xmlMemMutex);

#ifdef DEBUG_MEMORY
  xmlGenericError(xmlGenericErrorContext,
                  "Malloc(%d) Ok\n",size);
#endif

  if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();

  ret = HDR_2_CLIENT(p);

  if (xmlMemTraceBlockAt == ret)
  {
    xmlGenericError(xmlGenericErrorContext,
                    "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, (long)size);
    xmlMallocBreakpoint();
  }

  TEST_POINT

  return(ret);
}
Exemple #4
0
char *
xmlMemStrdupLoc(const char *str, const char *file, int line)
{
  char *s;
  size_t size = strlen(str) + 1;
  MEMHDR *p;

  if (!xmlMemInitialized) xmlInitMemory();
  TEST_POINT

  p = (MEMHDR *) malloc(RESERVE_SIZE+size);
  if (!p)
  {
    goto error;
  }
  p->mh_tag = MEMTAG;
  p->mh_size = size;
  p->mh_type = STRDUP_TYPE;
  p->mh_file = file;
  p->mh_line = line;
  xmlMutexLock(xmlMemMutex);
  p->mh_number = ++block;
  debugMemSize += size;
  debugMemBlocks++;
  if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
  debugmem_list_add(p);
#endif
  xmlMutexUnlock(xmlMemMutex);

  s = (char *) HDR_2_CLIENT(p);

  if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();

  if (s != NULL)
    strcpy(s,str);
  else
    goto error;

  TEST_POINT

  if (xmlMemTraceBlockAt == s)
  {
    xmlGenericError(xmlGenericErrorContext,
                    "%p : Strdup() Ok\n", xmlMemTraceBlockAt);
    xmlMallocBreakpoint();
  }

  return(s);

error:
  return(NULL);
}
void *
xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
{
    MEMHDR *p;
    unsigned long number;

    if (!xmlMemInitialized) xmlInitMemory();
    if (ptr == NULL)
        return(NULL);
    TEST_POINT

    p = CLIENT_2_HDR(ptr);
    number = p->mh_number;
    if (p->mh_tag != MEMTAG) {
       Mem_Tag_Err(p);
	 goto error;
    }
    p->mh_tag = ~MEMTAG;
    debugMemSize -= p->mh_size;
#ifdef MEM_LIST
    debugmem_list_delete(p);
#endif

    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
    if (!p) {
	 goto error;
    }
    if (xmlMemTraceBlockAt == ptr) {
	xmlGenericError(xmlGenericErrorContext,
			"%p : Realloced(%d -> %d) Ok\n",
			xmlMemTraceBlockAt, p->mh_size, size);
	xmlMallocBreakpoint();
    }
    p->mh_tag = MEMTAG;
    p->mh_number = number;
    p->mh_type = REALLOC_TYPE;
    p->mh_size = size;
    p->mh_file = file;
    p->mh_line = line;
    debugMemSize += size;
    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
    debugmem_list_add(p);
#endif

    TEST_POINT

    return(HDR_2_CLIENT(p));
    
error:    
    return(NULL);
}
Exemple #6
0
static void
xmlMemContentShow(FILE *fp, MEMHDR *p)
{
    int i,j,k,len;
    const char *buf;

    if (p == NULL) {
	fprintf(fp, " NULL");
	return;
    }
    len = p->mh_size;
    buf = (const char *) HDR_2_CLIENT(p);

    for (i = 0;i < len;i++) {
        if (buf[i] == 0) break;
	if (!isprint((unsigned char) buf[i])) break;
    }
    if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
        if (len >= 4) {
	    MEMHDR *q;
	    void *cur;

            for (j = 0;(j < len -3) && (j < 40);j += 4) {
		cur = *((void **) &buf[j]);
		q = CLIENT_2_HDR(cur);
		p = memlist;
		k = 0;
		while (p != NULL) {
		    if (p == q) break;
		    p = p->mh_next;
		    if (k++ > 100) break;
		}
		if ((p != NULL) && (p == q)) {
		    fprintf(fp, " pointer to #%lu at index %d",
		            p->mh_number, j);
		    return;
		}
	    }
	}
    } else if ((i == 0) && (buf[i] == 0)) {
        fprintf(fp," null");
    } else {
        if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
	else {
            fprintf(fp," [");
	    for (j = 0;j < i;j++)
                fprintf(fp,"%c", buf[j]);
            fprintf(fp,"]");
	}
    }
}
Exemple #7
0
void *
mem_alloc_ (
    MEMTRN     *trn,                    /*  Associated transaction           */
    size_t      size,                   /*  Desired size of memory block     */
    const char *filename,               /*  Name of source file making call  */
    word        lineno                  /*  Line number in calling source    */
)
{
    MEMHDR
       *ptr;                            /*  Allocated memory block           */

    /*  Allocate block with extra space for the header                       */
    ASSERT (size > 0);                  /*  Cannot allocate zero bytes!      */

    ptr = malloc (RESERVE_SIZE + size);
    if (ptr == NULL)                    /*  If nothing free, do a hunt       */
      {                                 /*    and try again...               */
        mem_scavenge ();
        ptr = malloc (RESERVE_SIZE + size);
        if (ptr == NULL)
            return (NULL);              /*  Really in trouble now!           */
      }
#   if (defined (MEM_TRACE))
    if (filename)
        trace ("%s (%d): alloc %d bytes->%p", filename, lineno, size, ptr);
#   endif

    ptr-> tag  = MEMTAG;                /*  Initialise block header          */
    ptr-> size = size;                  /*  Size of block                    */
    ptr-> file = filename;              /*  Who allocated it                 */
    ptr-> line = lineno;                /*    and where                      */

    if (!trn)                           /*  If no transaction then use the   */
        trn = &mem_list;                /*  main block list                  */

    list_reset (ptr);                   /*  Set up new block as list         */
    list_relink_before (ptr,            /*  Add to list of blocks            */
                        &trn-> memhdr);

    mem_total += size;                  /*  Keep count of space used         */
    mem_alloc_count += 1;               /*    and number of allocations      */

    return (HDR_2_CLIENT (ptr));        /*   and return client address       */
}
Exemple #8
0
/*
 *  MEMDBG_alloc_align
 *  Allocate a memory block. makes a protected call to malloc(), allocating
 *  extra data, and adding data to all required structures.
 */
void * MEMDBG_alloc_align(size_t size, int align, char *file, int line)
{
	MEMDBG_HDR      *p, *p2;
	char *p3;

	if ( ((signed long long)mem_size) < 0)
		fprintf(stderr, "MEMDBG_alloc_align "LLd" %s:%d  mem:"LLd"\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);

	p = (MEMDBG_HDR*)malloc(RESERVE_SZ_AL(align) + size + 4);
	if (!p) {
		if ( ((signed long long)mem_size) < 0)
			fprintf(stderr, "MEMDBG_alloc_align (end) "LLd" %s:%d  mem:"LLd"\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);
		return NULL;
	}

	p3 = ((char*)p)+RESERVE_SZ+align-1-4;
	p3 -= ((size_t)p3)%align;
	if ( (((size_t)p3)/align) % align == 0)
		p3 += align;
	p->mdbg_hdr1 = (MEMDBG_HDR2*)(p3-4);
	p2 = CLIENT_2_HDR_PTR(p3);
	memcpy(p2, &p, sizeof(p));
	memcpy(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOST, 4);
	p->mdbg_size = size;
	p->mdbg_file = file;
	p->mdbg_line = line;
	p->mdbg_hdr2 = (MEMDBG_HDR2*)(p3 + size);
	memcpy(p->mdbg_hdr2, cpMEMFPOST, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
	{
		p->mdbg_cnt = ++alloc_cnt;
		mem_size += size;
		if (mem_size > max_mem_size)
			max_mem_size = mem_size;
		MEMDBG_LIST_add(p);
	}
	if ( ((signed long long)mem_size) < 0)
		fprintf(stderr, "MEMDBG_alloc_align (end) "LLd" %s:%d  mem:"LLd"\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);
	return HDR_2_CLIENT(p);
}
Exemple #9
0
/* NOTE, there is no LIST_delete() for the freed list. We only put
 * data onto this list, it is kept for full runtime. We may want to
 * later add some way for the app to clean it up, but for now, we
 * add it, and keep it all.
 */
static void   MEMDBG_FREEDLIST_add(MEMDBG_HDR *p)
{
	unsigned char *cp;
	size_t i;

#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
	{
		freed_mem_size += p->mdbg_size;
		++freed_cnt;
		p->mdbg_next = freed_memlist;
		p->mdbg_prev = NULL;
		if (freed_memlist != NULL)
			freed_memlist->mdbg_prev = p;
		freed_memlist = p;
		/* Ok, now 'DEADBEEF' the original data buffer */
		cp = (unsigned char*)HDR_2_CLIENT(p);
		for (i = 0; i < p->mdbg_size; ++i)
			*cp++ = 0xCD;
	}
}
Exemple #10
0
void *
xmlReallocLoc(void *ptr,unsigned int size, const char * file, int line)
{
    MEMHDR *p;
    unsigned long number;
#ifdef DEBUG_MEMORY
    unsigned int oldsize;
#endif

    if (ptr == NULL)
        return(xmlMallocLoc(size, file, line));

    if (!xmlMemInitialized) xmlInitMemory();
    TEST_POINT

    p = CLIENT_2_HDR(ptr);
    number = p->mh_number;
    if (xmlMemStopAtBlock == number) xmlMallocBreakpoint();
    if (p->mh_tag != MEMTAG) {
       Mem_Tag_Err(p);
	 goto error;
    }
    p->mh_tag = ~MEMTAG;
    xmlMutexLock(xmlMemMutex);
    debugMemSize -= p->mh_size;
    debugMemBlocks--;
#ifdef DEBUG_MEMORY
    oldsize = p->mh_size;
#endif
#ifdef MEM_LIST
    debugmem_list_delete(p);
#endif
    xmlMutexUnlock(xmlMemMutex);

    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
    if (!p) {
	 goto error;
    }
    if (xmlMemTraceBlockAt == ptr) {
	xmlGenericError(xmlGenericErrorContext,
			"%p : Realloced(%ld -> %ld) Ok\n",
			xmlMemTraceBlockAt, p->mh_size, size);
	xmlMallocBreakpoint();
    }
    p->mh_tag = MEMTAG;
    p->mh_number = number;
    p->mh_type = REALLOC_TYPE;
    p->mh_size = size;
    p->mh_file = file;
    p->mh_line = line;
    xmlMutexLock(xmlMemMutex);
    debugMemSize += size;
    debugMemBlocks++;
    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
    debugmem_list_add(p);
#endif
    xmlMutexUnlock(xmlMemMutex);

    TEST_POINT

#ifdef DEBUG_MEMORY
    xmlGenericError(xmlGenericErrorContext,
	    "Realloced(%d to %d) Ok\n", oldsize, size);
#endif
    return(HDR_2_CLIENT(p));

error:
    return(NULL);
}
Exemple #11
0
/*
 *  MEMDBG_realloc
 *  Reallocate a memory block makes a protected call to realloc(), allocating
 *  extra data, and adding data to all required structures.
 *  *** realloc is a NASTY function.  The code here has taken a few turns,
 *  trying to handle all of the nuances of this function, and how we hook it,
 *  and how we deal with trying to not free data (if in MEMDBG_EXTRA_CHECKS mode)
 */
void *
MEMDBG_realloc(const void *ptr, size_t size, char *file, int line)
{
	MEMDBG_HDR *p;
	int istiny=0;
	int err=0, i;

	if ( ((signed long long)mem_size) < 0)
		fprintf(stderr, "MEMDBG_realloc(%lld) %s:%d  mem:%lld\n", (unsigned long long)size, file, line, (unsigned long long)mem_size);

	/* if ptr is null, this function works just like alloc, so simply use alloc */
	if (!ptr)
		return MEMDBG_alloc(size, file, line);

#ifdef _OPENMP
#pragma omp critical
#endif
	{
		p = CLIENT_2_HDR(ptr);
		if (p->mdbg_fpst == MEMFPOSTt)
			istiny = 1;
		else if (p->mdbg_fpst != MEMFPOST)
			err = 1;
		else {
			for (i = 0; i < 4; ++i)
				if (((char*)(p->mdbg_hdr2->mdbg_fpst))[i] != cpMEMFPOST[i]) {
					err = 1;
					break;
				}
		}
		if (err) {
			if (p->mdbg_fpst == MEMFPOSTd)
				err = 2;
			else {
				for (i = 0; i < 4; ++i)
					if (((char*)(p->mdbg_hdr2->mdbg_fpst))[i] != cpMEMFPOSTd[i]) {
						break;
					}
				if (i < 4)
					err = 2;
			}

		}
	}
	if (err) {
		if (err == 2)
			mem_fence_post_errd(p, file, line);
		else
			mem_fence_post_err(p, file, line);
		return NULL;
	}
	/* if size == 0, this function works exactly like free, so just use free */
	if (!size) {
		/* NOTE, use ptr, and NOT p */
		MEMDBG_free(ptr, file, line);
		return NULL;
	}
	p->mdbg_fpst = MEMFPOSTd;
	memcpy(p->mdbg_hdr2->mdbg_fpst, cpMEMFPOSTd, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
	{
		if (istiny)
			mem_sizet -= p->mdbg_size;
		else
			mem_size -= p->mdbg_size;
		MEMDBG_LIST_delete(p);
	}
#ifdef MEMDBG_EXTRA_CHECKS
	if (size > p->mdbg_size) {
		void *p2 = MEMDBG_alloc(size, file, line);
		if (p2) {
			if (istiny)
				MEMDBG_tag_mem_from_alloc_tiny(p);
			memcpy(p2, ((char*)p)+RESERVE_SZ, p->mdbg_size);
			/* we had to keep the original data 'clean' until now.
			 * but Now, we can put it on free list (which smashes
			 * the original memory block
			 */
			MEMDBG_FREEDLIST_add(p);
			return p2;
		}
		/* We have to undo the MEMDBG_LIST_delete(p); because realloc should
		 * leave the ORIGINAL buffer alone, if we can not allocate more
		 * memory.  Thus we need to 'leave' the leak alone. This is a leak
		 * unless the client code frees the original pointer.  'undoing' the
		 * MEMDBG_LIST_delete(p) keeps our code knowing this is a lost pointer.
		 */
		p->mdbg_fpst = MEMFPOST;
		memcpy(p->mdbg_hdr2, cpMEMFPOST, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
		{
			mem_size += p->mdbg_size;
			if (mem_size > max_mem_size)
				max_mem_size = mem_size;
			MEMDBG_LIST_add(p);
		}
		if (istiny)
			MEMDBG_tag_mem_from_alloc_tiny(p);
		return NULL;
	}
	/* NOTE, it is assumed that the memory will NOT be freed, so we simply drop
	   through, and allow normal realloc to work, and DO NOT try to put anything
	   onto the FREEDLIST, since it will just be the same block */
#endif
	p = (MEMDBG_HDR *) realloc(p, RESERVE_SZ + size + 4);
#ifdef MEMDBG_EXTRA_CHECKS
#ifdef _OPENMP
	{
		int i = 0;
		do {
#pragma omp critical (memdbg_crit)
			{
				if (!p && freed_mem_size > (RESERVE_SZ + size + 4) && !p && freed_cnt)
					i = 1;
			}
			if (i) {
				release_oldest_freed_block();
				p = (MEMDBG_HDR*)realloc(CLIENT_2_HDR(ptr), RESERVE_SZ + size + 4);
			}
		} while (i && !p);
	}
#else
	/* this is the 'right' block, but hard to do with the restrictions of no branching out that omp critical places on us */
	if (!p && freed_mem_size > (RESERVE_SZ + size + 4)) {
		while (!p && freed_cnt) {
			release_oldest_freed_block();
			p = (MEMDBG_HDR*)realloc(CLIENT_2_HDR(ptr), RESERVE_SZ + size + 4);
		}
	}
#endif
#endif
	if (!p)
	{
		/* We have to undo the MEMDBG_LIST_delete(p); because realloc should
			* leave the ORIGINAL buffer alone, if we can not allocate more
			* memory.  Thus we need to 'leave' the leak alone.
			*/
		p = CLIENT_2_HDR(ptr);	/* we have to get 'original' pointer again */
		p->mdbg_fpst = MEMFPOST;
		memcpy(p->mdbg_hdr2, cpMEMFPOST, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
		{
			mem_size += p->mdbg_size;
			if (mem_size > max_mem_size)
				max_mem_size = mem_size;
			MEMDBG_LIST_add(p);
		}
		if (istiny)
			MEMDBG_tag_mem_from_alloc_tiny(p);
		return NULL;
	}
	p->mdbg_fpst = MEMFPOST;
	p->mdbg_size = size;
	p->mdbg_file = file;
	p->mdbg_line = line;
	p->mdbg_hdr2 = (MEMDBG_HDR2*)(((char*)p)+RESERVE_SZ + size);
	memcpy(p->mdbg_hdr2, cpMEMFPOST, 4);
#ifdef _OPENMP
#pragma omp critical (memdbg_crit)
#endif
	{
		p->mdbg_cnt = ++alloc_cnt;
		mem_size += size;
		if (mem_size > max_mem_size)
			max_mem_size = mem_size;
		MEMDBG_LIST_add(p);
	}
	if (istiny)
		MEMDBG_tag_mem_from_alloc_tiny(p);
	return HDR_2_CLIENT(p);
}
Exemple #12
0
void MemDbg_Validate_msg2(int level, const char *pMsg, int bShowExMessages) {
	/* Level 0 we ALWAYS walk the alloc list, looking for over/underwrite, and validate a few other items. */
	MEMDBG_HDR  *p = memlist;
	int error = 0;
	int cnt=0;
#ifdef MEMDBG_EXTRA_CHECKS
	unsigned char *cp;
	unsigned i;
#endif
	if (bShowExMessages) {
		if (pMsg)
			fprintf(stderr, "%s\n", pMsg);
		fprintf(stderr, "MemDbg_Validate level 0 checking");
	}
	while (p) {
		if (memcmp(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOST, 4) && memcmp(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOSTt, 4)) {
			++cnt;
			if (cnt < 100) {
				if (!memcmp(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOSTd, 4))
					fprintf(stderr, "\nDeleted memory still in chain\n");
				else {
					fprintf(stderr, "\nMemory buffer underwrite found! Will try to list what file/line allocated the buffer\n");
					mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
				}
			}
			error = 1;
		}
		if (memcmp(p->mdbg_hdr2->mdbg_fpst, cpMEMFPOST, 4)) {
			++cnt;
			if (cnt < 100) {
				if (!memcmp(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOSTd, 4)) {
				} else {
					fprintf(stderr, "\nMemory buffer overwrite found! Will try to list what file/line allocated the buffer\n");
					mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
				}
			}
			error = 1;
		}
		// Loop detect code
		{
			MEMDBG_HDR  volatile *p2 = p->mdbg_next;
			while (p2) {
				if (p2 == p || p2 == p2->mdbg_next) {
					fprintf (stderr, "Error, internal loop in the memdbg linked list, aborting\n");
					break;
				}
				p2 = p2->mdbg_next;
			}
		}
		if (cnt > 1000)
			break;
		p = p->mdbg_next;
	}
	if (error) {
		fprintf(stderr, "\nExiting due to the error detected\n");
		if (cnt > 100)
			fprintf(stderr, "There were %d total errors, only first 100 shown\n", cnt);
		exit(1);
	}
	if (bShowExMessages)
		fprintf(stderr, " Passed\n");
	if (level == MEMDBG_VALIDATE_MIN) return;

#ifdef MEMDBG_EXTRA_CHECKS
	// Ok, we have a list of all freed items. We will do work on this.
	p = freed_memlist;
	if (!p) return;
	cnt = 0;
	if (bShowExMessages)
		fprintf(stderr, "MemDbg_Validate level 1 checking");
	while (p) {
		if (memcmp(p->mdbg_hdr1->mdbg_fpst, cpMEMFPOSTd, 4)) {
			++cnt;
			if (cnt < 100)
				fprintf(stderr, "\nFreed Memory buffer underwrite found! Will try to list what file/line allocated the buffer\n");
			mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
			error = 1;
		}
		if (memcmp(p->mdbg_hdr2->mdbg_fpst, cpMEMFPOSTd, 4)) {
			++cnt;
			if (cnt < 100)
				fprintf(stderr, "\nFreed Memory buffer overwrite found! Will try to list what file/line allocated the buffer\n");
			mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
			error = 1;
		}
		// Loop detect code
		{
			MEMDBG_HDR  *p2 = p->mdbg_next;
			while (p2) {
				if (p2 == p || p2 == p2->mdbg_next) {
					fprintf (stderr, "Error, internal loop in the memdbg linked list, aborting\n");
					break;
				}
				p2 = p2->mdbg_next;
			}
		}
		if (cnt > 1000)
			break;
		p = p->mdbg_next;
	}
	if (error) {
		fprintf(stderr, "\nExiting due to the error detected\n");
		if (cnt > 100)
			fprintf(stderr, "There were %d total errors, only first 100 shown\n", cnt);
		exit(1);
	}
	if (bShowExMessages)
		fprintf(stderr, " Passed\n");
	if (level == MEMDBG_VALIDATE_DEEP) return;

	p = freed_memlist;
	cnt = 0;
	if (bShowExMessages)
		fprintf(stderr, "MemDbg_Validate level 2 checking");
	while (p) {
		cp = (unsigned char*)HDR_2_CLIENT(p);
		if (p->mdbg_size != p->mdbg_hdr2->mdbg_fpst - cp) {
			fprintf(stderr, "\nFreed Memory buffer underwrite found (size var busted)! Will try to list what file/line allocated the buffer\n");
			mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
			error = 1;
		} else {
			for (i = 0; i < p->mdbg_size; ++i) {
				// in 'deeper' mode, we only look at first 8 bytes.  If these are not overwritten, it is less likely that the buffer
				// has been written to.  It 'can' be written to later on, and if we use deepest, we will look at the FULL buffer.
				if (i == 8)
					break;
				if (*cp++ != 0xCD) {
					++cnt;
					if (cnt < 100)
						fprintf(stderr, "\nFreed Memory buffer modification found! Will try to list what file/line allocated the buffer\n");
					mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
					error = 1;
					break;
				}
			}
		}
		// Loop detect code
		{
			MEMDBG_HDR  *p2 = p->mdbg_next;
			while (p2) {
				if (p2 == p || p2 == p2->mdbg_next) {
					fprintf (stderr, "Error, internal loop in the memdbg linked list, aborting\n");
					break;
				}
				p2 = p2->mdbg_next;
			}
		}
		if (cnt > 1000)
			break;
		p = p->mdbg_next;
	}
	if (error) {
		fprintf(stderr, "\nExiting due to the error detected\n");
		if (cnt > 100)
			fprintf(stderr, "There were %d total errors, only first 100 shown\n", cnt);
		exit(1);
	}
	if (bShowExMessages)
		fprintf(stderr, " Passed\n");
	if (level == MEMDBG_VALIDATE_DEEPER) return;

	p = freed_memlist;
	cnt = 0;
	if (bShowExMessages)
		fprintf(stderr, "MemDbg_Validate level 3 checking");
	while (p) {
		cp = (unsigned char*)HDR_2_CLIENT(p);
		// in this deepest mode, we look at the ENTIRE buffer.  In deeper, we looked at first 8, so here, we just start from 8 and look forward.
		for (i = 8; i < p->mdbg_size; ++i) {
			if (*cp++ != 0xCD) {
				++cnt;
				if (cnt < 100)
					fprintf(stderr, "\nFreed Memory buffer modification found! Will try to list what file/line allocated the buffer\n");
				mem_fence_post_err_ne(p, p->mdbg_file, p->mdbg_line);
				error = 1;
				break;
			}
		}
		// Loop detect code
		{
			MEMDBG_HDR  *p2 = p->mdbg_next;
			while (p2) {
				if (p2 == p || p2 == p2->mdbg_next) {
					fprintf (stderr, "Error, internal loop in the memdbg linked list, aborting\n");
					break;
				}
				p2 = p2->mdbg_next;
			}
		}
		if (cnt > 1000)
			break;
		p = p->mdbg_next;
	}
	if (error) {
		fprintf(stderr, "\nExiting due to the error detected\n");
		if (cnt > 100)
			fprintf(stderr, "There were %d total errors, only first 100 shown\n", cnt);
		exit(1);
	}
	if (bShowExMessages)
		fprintf(stderr, " Passed\n");
#endif
}