xmlMemDisplayLast: : a FILE descriptor used as the output file, if NULL, the result is written to the file .memorylist : the amount of memory to dump
the last nbBytes of memory allocated and not freed, useful for dumping the memory left allocated between two places at runtime.
{
#ifdef MEM_LIST
MEMHDR *p;
unsigned idx;
int nb = 0;
#endif
FILE *old_fp = fp;
if (nbBytes <= 0)
return;
if (fp == NULL) {
fp = fopen(".memorylist", "w");
if (fp == NULL)
return;
}
#ifdef MEM_LIST
fprintf(fp," Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n",
nbBytes, debugMemSize, debugMaxMemSize);
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
idx = 0;
xmlMutexLock(xmlMemMutex);
p = memlist;
while ((p) && (nbBytes > 0)) {
fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
(unsigned long)p->mh_size);
switch (p->mh_type) {
case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break;
case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
default:
fprintf(fp,"Unknown memory block, may be corrupted");
xmlMutexUnlock(xmlMemMutex);
if (old_fp == NULL)
fclose(fp);
return;
}
if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
if (p->mh_tag != MEMTAG)
fprintf(fp," INVALID");
nb++;
if (nb < 100)
xmlMemContentShow(fp, p);
else
fprintf(fp," skip");
fprintf(fp,"\n");
nbBytes -= (unsigned long)p->mh_size;
p = p->mh_next;
}
xmlMutexUnlock(xmlMemMutex);
#else
fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
#endif
if (old_fp == NULL)
fclose(fp);
}