1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-23 01:52:48 +03:00

add xmlMemDisplayLast to help debug incremental memory leaks, and some

* include/libxml/xmlmemory.h xmlmemory.c: add xmlMemDisplayLast to
  help debug incremental memory leaks, and some cleanups
* runxmlconf.c: use that new call and avoid ever touching the
  system catalog in the regression tests
Daniel

svn path=/trunk/; revision=3760
This commit is contained in:
Daniel Veillard
2008-07-30 12:58:11 +00:00
parent 40ec29a56f
commit 09459bf107
4 changed files with 141 additions and 82 deletions

View File

@@ -1,3 +1,10 @@
Wed Jul 30 14:55:54 CEST 2008 Daniel Veillard <daniel@veillard.com>
* include/libxml/xmlmemory.h xmlmemory.c: add xmlMemDisplayLast to
help debug incremental memory leaks, and some cleanups
* runxmlconf.c: use that new call and avoid ever touching the
system catalog in the regression tests
Wed Jul 30 14:33:33 CEST 2008 Daniel Veillard <daniel@veillard.com> Wed Jul 30 14:33:33 CEST 2008 Daniel Veillard <daniel@veillard.com>
* parser.c include/libxml/xmlerror.h: an XML-1.0 document can't load * parser.c include/libxml/xmlerror.h: an XML-1.0 document can't load

View File

@@ -20,7 +20,7 @@
* *
* DEBUG_MEMORY replaces the allocator with a collect and debug * DEBUG_MEMORY replaces the allocator with a collect and debug
* shell to the libc allocator. * shell to the libc allocator.
* DEBUG_MEMORY should only be activated when debugging * DEBUG_MEMORY should only be activated when debugging
* libxml i.e. if libxml has been configured with --with-debug-mem too. * libxml i.e. if libxml has been configured with --with-debug-mem too.
*/ */
/* #define DEBUG_MEMORY_FREED */ /* #define DEBUG_MEMORY_FREED */
@@ -35,7 +35,7 @@
/** /**
* DEBUG_MEMORY_LOCATION: * DEBUG_MEMORY_LOCATION:
* *
* DEBUG_MEMORY_LOCATION should be activated only when debugging * DEBUG_MEMORY_LOCATION should be activated only when debugging
* libxml i.e. if libxml has been configured with --with-debug-mem too. * libxml i.e. if libxml has been configured with --with-debug-mem too.
*/ */
#ifdef DEBUG_MEMORY_LOCATION #ifdef DEBUG_MEMORY_LOCATION
@@ -105,18 +105,18 @@ XMLPUBFUN int XMLCALL
xmlMallocFunc mallocFunc, xmlMallocFunc mallocFunc,
xmlReallocFunc reallocFunc, xmlReallocFunc reallocFunc,
xmlStrdupFunc strdupFunc); xmlStrdupFunc strdupFunc);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlMemGet (xmlFreeFunc *freeFunc, xmlMemGet (xmlFreeFunc *freeFunc,
xmlMallocFunc *mallocFunc, xmlMallocFunc *mallocFunc,
xmlReallocFunc *reallocFunc, xmlReallocFunc *reallocFunc,
xmlStrdupFunc *strdupFunc); xmlStrdupFunc *strdupFunc);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlGcMemSetup (xmlFreeFunc freeFunc, xmlGcMemSetup (xmlFreeFunc freeFunc,
xmlMallocFunc mallocFunc, xmlMallocFunc mallocFunc,
xmlMallocFunc mallocAtomicFunc, xmlMallocFunc mallocAtomicFunc,
xmlReallocFunc reallocFunc, xmlReallocFunc reallocFunc,
xmlStrdupFunc strdupFunc); xmlStrdupFunc strdupFunc);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlGcMemGet (xmlFreeFunc *freeFunc, xmlGcMemGet (xmlFreeFunc *freeFunc,
xmlMallocFunc *mallocFunc, xmlMallocFunc *mallocFunc,
xmlMallocFunc *mallocAtomicFunc, xmlMallocFunc *mallocAtomicFunc,
@@ -126,42 +126,44 @@ XMLPUBFUN int XMLCALL
/* /*
* Initialization of the memory layer. * Initialization of the memory layer.
*/ */
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlInitMemory (void); xmlInitMemory (void);
/* /*
* Cleanup of the memory layer. * Cleanup of the memory layer.
*/ */
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlCleanupMemory (void); xmlCleanupMemory (void);
/* /*
* These are specific to the XML debug memory wrapper. * These are specific to the XML debug memory wrapper.
*/ */
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlMemUsed (void); xmlMemUsed (void);
XMLPUBFUN int XMLCALL XMLPUBFUN int XMLCALL
xmlMemBlocks (void); xmlMemBlocks (void);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlMemDisplay (FILE *fp); xmlMemDisplay (FILE *fp);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlMemDisplayLast(FILE *fp, long nbBytes);
XMLPUBFUN void XMLCALL
xmlMemShow (FILE *fp, int nr); xmlMemShow (FILE *fp, int nr);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlMemoryDump (void); xmlMemoryDump (void);
XMLPUBFUN void * XMLCALL XMLPUBFUN void * XMLCALL
xmlMemMalloc (size_t size); xmlMemMalloc (size_t size);
XMLPUBFUN void * XMLCALL XMLPUBFUN void * XMLCALL
xmlMemRealloc (void *ptr,size_t size); xmlMemRealloc (void *ptr,size_t size);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlMemFree (void *ptr); xmlMemFree (void *ptr);
XMLPUBFUN char * XMLCALL XMLPUBFUN char * XMLCALL
xmlMemoryStrdup (const char *str); xmlMemoryStrdup (const char *str);
XMLPUBFUN void * XMLCALL XMLPUBFUN void * XMLCALL
xmlMallocLoc (size_t size, const char *file, int line); xmlMallocLoc (size_t size, const char *file, int line);
XMLPUBFUN void * XMLCALL XMLPUBFUN void * XMLCALL
xmlReallocLoc (void *ptr, size_t size, const char *file, int line); xmlReallocLoc (void *ptr, size_t size, const char *file, int line);
XMLPUBFUN void * XMLCALL XMLPUBFUN void * XMLCALL
xmlMallocAtomicLoc (size_t size, const char *file, int line); xmlMallocAtomicLoc (size_t size, const char *file, int line);
XMLPUBFUN char * XMLCALL XMLPUBFUN char * XMLCALL
xmlMemStrdupLoc (const char *str, const char *file, int line); xmlMemStrdupLoc (const char *str, const char *file, int line);

View File

@@ -125,38 +125,14 @@ static int addEntity(char *name, char *content) {
/* /*
* We need to trap calls to the resolver to not account memory for the catalog * We need to trap calls to the resolver to not account memory for the catalog
* which is shared to the current running test. We also don't want to have * and not rely on any external resources.
* network downloads modifying tests.
*/ */
static xmlParserInputPtr static xmlParserInputPtr
testExternalEntityLoader(const char *URL, const char *ID, testExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) { xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret; xmlParserInputPtr ret;
int i;
for (i = 0;i < nb_entities;i++) { ret = xmlNewInputFromFile(ctxt, (const char *) URL);
if (!strcmp(testEntitiesName[i], URL)) {
ret = xmlNewStringInputStream(ctxt,
(const xmlChar *) testEntitiesValue[i]);
if (ret != NULL) {
ret->filename = (const char *)
xmlStrdup((xmlChar *)testEntitiesName[i]);
}
return(ret);
}
}
if (checkTestFile(URL)) {
ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
} else {
int memused = xmlMemUsed();
ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
extraMemoryFromResolver += xmlMemUsed() - memused;
}
#if 0
if (ret == NULL) {
fprintf(stderr, "Failed to find resource %s\n", URL);
}
#endif
return(ret); return(ret);
} }
@@ -377,6 +353,7 @@ xmlconfTestItem(xmlDocPtr doc, xmlNodePtr cur) {
test_log("test %s : %s leaked %d bytes\n", test_log("test %s : %s leaked %d bytes\n",
id, filename, final - mem); id, filename, final - mem);
nb_leaks++; nb_leaks++;
xmlMemDisplayLast(logfile, final - mem);
} }
nb_tests++; nb_tests++;

View File

@@ -34,7 +34,7 @@
/** /**
* MEM_LIST: * MEM_LIST:
* *
* keep track of all allocated blocks for error reporting * keep track of all allocated blocks for error reporting
* Always build the memory list ! * Always build the memory list !
*/ */
#ifdef DEBUG_MEMORY_LOCATION #ifdef DEBUG_MEMORY_LOCATION
@@ -162,7 +162,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
{ {
MEMHDR *p; MEMHDR *p;
void *ret; void *ret;
if (!xmlMemInitialized) xmlInitMemory(); if (!xmlMemInitialized) xmlInitMemory();
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
@@ -170,7 +170,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
#endif #endif
TEST_POINT TEST_POINT
p = (MEMHDR *) malloc(RESERVE_SIZE+size); p = (MEMHDR *) malloc(RESERVE_SIZE+size);
if (!p) { if (!p) {
@@ -178,7 +178,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
"xmlMallocLoc : Out of free space\n"); "xmlMallocLoc : Out of free space\n");
xmlMemoryDump(); xmlMemoryDump();
return(NULL); return(NULL);
} }
p->mh_tag = MEMTAG; p->mh_tag = MEMTAG;
p->mh_size = size; p->mh_size = size;
p->mh_type = MALLOC_TYPE; p->mh_type = MALLOC_TYPE;
@@ -193,12 +193,12 @@ xmlMallocLoc(size_t size, const char * file, int line)
debugmem_list_add(p); debugmem_list_add(p);
#endif #endif
xmlMutexUnlock(xmlMemMutex); xmlMutexUnlock(xmlMemMutex);
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"Malloc(%d) Ok\n",size); "Malloc(%d) Ok\n",size);
#endif #endif
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
ret = HDR_2_CLIENT(p); ret = HDR_2_CLIENT(p);
@@ -230,7 +230,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
{ {
MEMHDR *p; MEMHDR *p;
void *ret; void *ret;
if (!xmlMemInitialized) xmlInitMemory(); if (!xmlMemInitialized) xmlInitMemory();
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
@@ -238,7 +238,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
#endif #endif
TEST_POINT TEST_POINT
p = (MEMHDR *) malloc(RESERVE_SIZE+size); p = (MEMHDR *) malloc(RESERVE_SIZE+size);
if (!p) { if (!p) {
@@ -246,7 +246,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
"xmlMallocLoc : Out of free space\n"); "xmlMallocLoc : Out of free space\n");
xmlMemoryDump(); xmlMemoryDump();
return(NULL); return(NULL);
} }
p->mh_tag = MEMTAG; p->mh_tag = MEMTAG;
p->mh_size = size; p->mh_size = size;
p->mh_type = MALLOC_ATOMIC_TYPE; p->mh_type = MALLOC_ATOMIC_TYPE;
@@ -266,7 +266,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"Malloc(%d) Ok\n",size); "Malloc(%d) Ok\n",size);
#endif #endif
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
ret = HDR_2_CLIENT(p); ret = HDR_2_CLIENT(p);
@@ -341,7 +341,7 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
debugmem_list_delete(p); debugmem_list_delete(p);
#endif #endif
xmlMutexUnlock(xmlMemMutex); xmlMutexUnlock(xmlMemMutex);
p = (MEMHDR *) realloc(p,RESERVE_SIZE+size); p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
if (!p) { if (!p) {
goto error; goto error;
@@ -374,8 +374,8 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
"Realloced(%d to %d) Ok\n", oldsize, size); "Realloced(%d to %d) Ok\n", oldsize, size);
#endif #endif
return(HDR_2_CLIENT(p)); return(HDR_2_CLIENT(p));
error: error:
return(NULL); return(NULL);
} }
@@ -455,10 +455,10 @@ xmlMemFree(void *ptr)
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"Freed(%d) Ok\n", size); "Freed(%d) Ok\n", size);
#endif #endif
return; return;
error: error:
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlMemFree(%lX) error\n", (unsigned long) ptr); "xmlMemFree(%lX) error\n", (unsigned long) ptr);
xmlMallocBreakpoint(); xmlMallocBreakpoint();
@@ -504,16 +504,16 @@ xmlMemStrdupLoc(const char *str, const char *file, int line)
debugmem_list_add(p); debugmem_list_add(p);
#endif #endif
xmlMutexUnlock(xmlMemMutex); xmlMutexUnlock(xmlMemMutex);
s = (char *) HDR_2_CLIENT(p); s = (char *) HDR_2_CLIENT(p);
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
if (s != NULL) if (s != NULL)
strcpy(s,str); strcpy(s,str);
else else
goto error; goto error;
TEST_POINT TEST_POINT
if (xmlMemTraceBlockAt == s) { if (xmlMemTraceBlockAt == s) {
@@ -617,7 +617,7 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
} else if ((i == 0) && (buf[i] == 0)) { } else if ((i == 0) && (buf[i] == 0)) {
fprintf(fp," null"); fprintf(fp," null");
} else { } else {
if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
else { else {
fprintf(fp," ["); fprintf(fp," [");
for (j = 0;j < i;j++) for (j = 0;j < i;j++)
@@ -628,6 +628,79 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
} }
#endif #endif
/**
* xmlMemDisplayLast:
* @fp: a FILE descriptor used as the output file, if NULL, the result is
* written to the file .memorylist
* @nbBytes: 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.
*/
void
xmlMemDisplayLast(FILE *fp, long nbBytes)
{
#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);
}
/** /**
* xmlMemDisplay: * xmlMemDisplay:
* @fp: a FILE descriptor used as the output file, if NULL, the result is * @fp: a FILE descriptor used as the output file, if NULL, the result is
@@ -665,7 +738,7 @@ xmlMemDisplay(FILE *fp)
fprintf(fp," %s\n\n", buf); fprintf(fp," %s\n\n", buf);
#endif #endif
fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
debugMemSize, debugMaxMemSize); debugMemSize, debugMaxMemSize);
fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
@@ -742,7 +815,7 @@ static void debugmem_list_delete(MEMHDR *p)
* *
* internal error function. * internal error function.
*/ */
static void debugmem_tag_error(void *p) static void debugmem_tag_error(void *p)
{ {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
@@ -802,7 +875,7 @@ xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED)
} }
} }
xmlMutexUnlock(xmlMemMutex); xmlMutexUnlock(xmlMemMutex);
#endif /* MEM_LIST */ #endif /* MEM_LIST */
} }
/** /**
@@ -849,11 +922,11 @@ xmlInitMemory(void)
{ {
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
char *breakpoint; char *breakpoint;
#endif #endif
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlInitMemory()\n"); "xmlInitMemory()\n");
#endif #endif
/* /*
This is really not good code (see Bug 130419). Suggestions for This is really not good code (see Bug 130419). Suggestions for
improvement will be welcome! improvement will be welcome!
@@ -867,18 +940,18 @@ xmlInitMemory(void)
if (breakpoint != NULL) { if (breakpoint != NULL) {
sscanf(breakpoint, "%ud", &xmlMemStopAtBlock); sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
} }
#endif #endif
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
breakpoint = getenv("XML_MEM_TRACE"); breakpoint = getenv("XML_MEM_TRACE");
if (breakpoint != NULL) { if (breakpoint != NULL) {
sscanf(breakpoint, "%p", &xmlMemTraceBlockAt); sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
} }
#endif #endif
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlInitMemory() Ok\n"); "xmlInitMemory() Ok\n");
#endif #endif
return(0); return(0);
} }
@@ -893,7 +966,7 @@ xmlCleanupMemory(void) {
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlCleanupMemory()\n"); "xmlCleanupMemory()\n");
#endif #endif
if (xmlMemInitialized == 0) if (xmlMemInitialized == 0)
return; return;
@@ -903,7 +976,7 @@ xmlCleanupMemory(void) {
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlCleanupMemory() Ok\n"); "xmlCleanupMemory() Ok\n");
#endif #endif
} }
/** /**
@@ -927,7 +1000,7 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlMemSetup()\n"); "xmlMemSetup()\n");
#endif #endif
if (freeFunc == NULL) if (freeFunc == NULL)
return(-1); return(-1);
if (mallocFunc == NULL) if (mallocFunc == NULL)
@@ -944,7 +1017,7 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlMemSetup() Ok\n"); "xmlMemSetup() Ok\n");
#endif #endif
return(0); return(0);
} }
@@ -994,7 +1067,7 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlGcMemSetup()\n"); "xmlGcMemSetup()\n");
#endif #endif
if (freeFunc == NULL) if (freeFunc == NULL)
return(-1); return(-1);
if (mallocFunc == NULL) if (mallocFunc == NULL)
@@ -1013,7 +1086,7 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlGcMemSetup() Ok\n"); "xmlGcMemSetup() Ok\n");
#endif #endif
return(0); return(0);
} }