Hi Daniel, All, I was hunting down why XML::LibXML Perl-binding fails to pass it's test-suit (with many segfaults) when linked to a recent release of libxml2 when I came to the following: in xmlParseBalancedChunkMemoryRecover a new document and a parser context are temporarily created (and freed at the end of that routine). The parser ctxt has a dict, which is also used as the newDoc's dict at line parse.c:11196 (CVS). newDoc->dict = ctxt->dict; xmlDictReference(newDoc->dict); Thus e.g. all element names of the parsed chunk are stored in this dictionary. But finally, both the parser ctxt and newDoc are destroyed and so is the dictionary. Thus, the resulting nodelist has invalid pointers in nodes' names. I guess, those two lines got there by mistake (we need the strings in the parsed chunk to exist even after the newDoc and ctxt are freed). At least, removing them fixes the segfaults :-) Below is a simple test-case I used. It doesn't segfault by itself on my box, but valgrind --tool=memcheck clearly identifies the problem as shown below: ==7383== Invalid read of size 4 ==7383== at 0x1B96EADB: xmlFreeNodeList__internal_alias (tree.c:3343) ==7383== by 0x804866A: main (parse2.c:14) ==7383== Address 0x1BBD64B8 is 80 bytes inside a block of size 88 free'd ==7383== at 0x1B902391: free (in /usr/lib/valgrind/vgpreload_memcheck.so) ==7383== by 0x1B96B89D: xmlFreeDoc__internal_alias (tree.c:1160) ==7383== by 0x1B9674B3: xmlParseBalancedChunkMemoryRecover__internal_alias (parser.c:11277) ==7383== by 0x1B9666FC: xmlParseBalancedChunkMemory__internal_alias (parser.c:10763) ==7383== ==7383== Invalid read of size 4 ==7383== at 0x1BA133FB: xmlDictOwns__internal_alias (dict.c:709) ==7383== by 0x1B96EC5C: xmlFreeNodeList__internal_alias (tree.c:3380) ==7383== by 0x804866A: main (parse2.c:14) ==7383== Address 0x1BBD38C0 is 16 bytes inside a block of size 24 free'd ==7383== at 0x1B902391: free (in /usr/lib/valgrind/vgpreload_memcheck.so) ==7383== by 0x1BA12DCA: xmlDictFree__internal_alias (dict.c:480) ==7383== by 0x1B96B8B1: xmlFreeDoc__internal_alias (tree.c:1161) ==7383== by 0x1B9674B3: xmlParseBalancedChunkMemoryRecover__internal_alias (parser.c:11277) ==7383== ==7383== Invalid read of size 4 ==7383== at 0x1BA1341A: xmlDictOwns__internal_alias (dict.c:711) ==7383== by 0x1B96EC5C: xmlFreeNodeList__internal_alias (tree.c:3380) ==7383== by 0x804866A: main (parse2.c:14) ==7383== Address 0x1BBD652C is 4 bytes inside a block of size 1024 free'd ==7383== at 0x1B902391: free (in /usr/lib/valgrind/vgpreload_memcheck.so) ==7383== by 0x1BA12DAF: xmlDictFree__internal_alias (dict.c:477) ==7383== by 0x1B96B8B1: xmlFreeDoc__internal_alias (tree.c:1161) ==7383== by 0x1B9674B3: xmlParseBalancedChunkMemoryRecover__internal_alias (parser.c:11277) ==7383== ==7383== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 23 from 1) ___parse2.c___ #include <stdio.h> #include <libxml/parser.h> #include <libxml/tree.h> int main (int argc, char **argv) { xmlNodePtr nodes = NULL; int retCode; LIBXML_TEST_VERSION retCode = xmlParseBalancedChunkMemory(NULL,NULL,NULL,0,"<A/>",&nodes); xmlFreeNodeList( nodes ); xmlCleanupParser(); xmlMemoryDump(); return(0); } __end_of_parse2.c___ Cheers, -- Petr
Attachment:
pgpcc9N3yd2vn.pgp
Description: PGP signature