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:
@@ -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>
|
||||
|
||||
* parser.c include/libxml/xmlerror.h: an XML-1.0 document can't load
|
||||
|
||||
@@ -143,6 +143,8 @@ XMLPUBFUN int XMLCALL
|
||||
xmlMemBlocks (void);
|
||||
XMLPUBFUN void XMLCALL
|
||||
xmlMemDisplay (FILE *fp);
|
||||
XMLPUBFUN void XMLCALL
|
||||
xmlMemDisplayLast(FILE *fp, long nbBytes);
|
||||
XMLPUBFUN void XMLCALL
|
||||
xmlMemShow (FILE *fp, int nr);
|
||||
XMLPUBFUN void XMLCALL
|
||||
|
||||
29
runxmlconf.c
29
runxmlconf.c
@@ -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
|
||||
* which is shared to the current running test. We also don't want to have
|
||||
* network downloads modifying tests.
|
||||
* and not rely on any external resources.
|
||||
*/
|
||||
static xmlParserInputPtr
|
||||
testExternalEntityLoader(const char *URL, const char *ID,
|
||||
xmlParserCtxtPtr ctxt) {
|
||||
xmlParserInputPtr ret;
|
||||
int i;
|
||||
|
||||
for (i = 0;i < nb_entities;i++) {
|
||||
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
|
||||
ret = xmlNewInputFromFile(ctxt, (const char *) URL);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@@ -377,6 +353,7 @@ xmlconfTestItem(xmlDocPtr doc, xmlNodePtr cur) {
|
||||
test_log("test %s : %s leaked %d bytes\n",
|
||||
id, filename, final - mem);
|
||||
nb_leaks++;
|
||||
xmlMemDisplayLast(logfile, final - mem);
|
||||
}
|
||||
nb_tests++;
|
||||
|
||||
|
||||
73
xmlmemory.c
73
xmlmemory.c
@@ -628,6 +628,79 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
|
||||
}
|
||||
#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:
|
||||
* @fp: a FILE descriptor used as the output file, if NULL, the result is
|
||||
|
||||
Reference in New Issue
Block a user