Hi, I think I found a bug in libxml-2: in my multi-threaded application
I get a memory leakage when I save an xml file
Here's an example of the output I get from valgrind
==4275== 981,552 bytes in 1,014 blocks are definitely lost in loss
record 44 of 44
==4275== at 0x4C2779D: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4275== by 0x4ED7EF1: xmlGetGlobalState (threads.c:584)
==4275== by 0x4ED7634: __xmlIndentTreeOutput (globals.c:921)
==4275== by 0x4F3D12C: xmlNodeListDumpOutput (xmlsave.c:722)
==4275== by 0x4F3C95E: xmlNodeDumpOutputInternal (xmlsave.c:979)
==4275== by 0x4F3D112: xmlNodeListDumpOutput (xmlsave.c:730)
==4275== by 0x4F3C95E: xmlNodeDumpOutputInternal (xmlsave.c:979)
==4275== by 0x4F3D112: xmlNodeListDumpOutput (xmlsave.c:730)
==4275== by 0x4F3C95E: xmlNodeDumpOutputInternal (xmlsave.c:979)
==4275== by 0x4F3D112: xmlNodeListDumpOutput (xmlsave.c:730)
==4275== by 0x4F3C95E: xmlNodeDumpOutputInternal (xmlsave.c:979)
==4275== by 0x4F3C4E1: xmlDocContentDumpOutput (xmlsave.c:1139)
In globals.c in case the calling thread is not the main thread,
__xmlIndentTreeOutput does
return (&xmlGetGlobalState()->xmlIndentTreeOutput);
but as it can be seen in threads.c:584 every time it is called it
mallocs memory for a xmlGlobalState.
This memory is never free'd, and this is the only reason why functions
calling __xmlIndentTreeOutput get a valid pointer and do not give a
segfault.
But, unfortunately, after returning from __xmlIndentTreeOutput, you
don't have any way to free the malloc'd memory any more and you have a
leakage.
Now, considering that I am a libxml-2.0 internals novice, I tried changing
int * __xmlIndentTreeOutput(void);
to
int __xmlIndentTreeOutput(void);
so that you just return the value and not a pointer. This solution break
parserInternals.c:2157 because it breaks
xmlIndentTreeOutput = 1;
since it is not a valid lvalue any more. I know this is bad, but I need
a quit fix for my application dying because of memory exhaustion.
I attach my patch, please evaluate if it is a good strategy.
Ottavio Campana
PS: a similar problem seems to exist in __xmlLastError ,
__xmlSaveNoEmptyTags , __xmlTreeIndentString , __xmlBufferAllocScheme ,
__xmlDefaultBufferSize , __xmlOutputBufferCreateFilenameValue ,
__htmlDefaultSAXHandler and __xmlGenericError . And maybe in others.
diff -ur libxml2-2.7.8.orig/globals.c libxml2-2.7.8/globals.c
--- libxml2-2.7.8.orig/globals.c 2010-10-12 08:25:32.000000000 +0200
+++ libxml2-2.7.8/globals.c 2012-02-06 14:30:30.023997685 +0100
@@ -913,12 +913,23 @@
}
#undef xmlIndentTreeOutput
-int *
+int
__xmlIndentTreeOutput(void) {
if (IS_MAIN_THREAD)
- return (&xmlIndentTreeOutput);
+ return xmlIndentTreeOutput;
else
- return (&xmlGetGlobalState()->xmlIndentTreeOutput);
+ {
+ int ret;
+ xmlGlobalState *gs;
+
+ gs = xmlGetGlobalState();
+ ret = gs->xmlIndentTreeOutput;
+
+ if (gs)
+ free (gs);
+
+ return ret;
+ }
}
int xmlThrDefIndentTreeOutput(int v) {
int ret;
diff -ur libxml2-2.7.8.orig/include/libxml/globals.h libxml2-2.7.8/include/libxml/globals.h
--- libxml2-2.7.8.orig/include/libxml/globals.h 2010-10-12 08:25:32.000000000 +0200
+++ libxml2-2.7.8/include/libxml/globals.h 2012-02-06 14:19:59.244017419 +0100
@@ -374,10 +374,10 @@
#endif
XMLPUBFUN int XMLCALL xmlThrDefGetWarningsDefaultValue(int v);
-XMLPUBFUN int * XMLCALL __xmlIndentTreeOutput(void);
+XMLPUBFUN int XMLCALL __xmlIndentTreeOutput(void);
#ifdef LIBXML_THREAD_ENABLED
#define xmlIndentTreeOutput \
-(*(__xmlIndentTreeOutput()))
+((__xmlIndentTreeOutput()))
#else
XMLPUBVAR int xmlIndentTreeOutput;
#endif
diff -ur libxml2-2.7.8.orig/parserInternals.c libxml2-2.7.8/parserInternals.c
--- libxml2-2.7.8.orig/parserInternals.c 2010-10-12 08:25:32.000000000 +0200
+++ libxml2-2.7.8/parserInternals.c 2012-02-06 14:32:18.827994269 +0100
@@ -2154,7 +2154,6 @@
int old = xmlKeepBlanksDefaultValue;
xmlKeepBlanksDefaultValue = val;
- if (!val) xmlIndentTreeOutput = 1;
return(old);
}
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
[email protected]
http://mail.gnome.org/mailman/listinfo/xml