Skip Menu |

This queue is for tickets about the XML-LibXML CPAN distribution.

Report information
The Basics
Id: 12765
Status: resolved
Priority: 0/
Queue: XML-LibXML

People
Owner: pajas [...] matfyz.cz
Requestors: khendrix [...] knobias.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.58
Fixed in: (no value)



Subject: Memory Leak
Distribution: XML-LibXML-1.58 LibXML version : 2.6.16 Summary When perl destroys a document created with the XML::LibXML parse_string method, it leaks ~88 bytes of memory. ----------- Test Box #1 ----------- [jobs@dev fix]$ uname -a Linux dev 2.4.21-4.EL #1 Fri Oct 3 18:13:58 EDT 2003 i686 i686 i386 GNU/Linux [jobs@dev fix]$ perl -V Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Platform: osname=linux, osvers=2.4.21-1.1931.2.393.entsmp, archname=i386-linux-thread-multi uname='linux por' config_args='-des -Doptimize=-O2 -g -pipe -march=i386 -mcpu=i686 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Dotherlibdirs=/usr/lib/perl5/5.8.0 -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef' useithreads=define usemultiplicity= useperlio= d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=un uselongdouble= usemymalloc=, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='3.2.3 20030502 (Red Hat Linux 3.2.3-19)', gccosandvers='' gccversion='3.2.3 200305' intsize=o, longsize=s, ptrsize=l, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long' k', ivsize=4' ivtype, nvtype='double' o_no', nvsize=, Off_t='', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc' l', ldflags =' -L/usr/local/lib' ldflags_use' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lgdbm -ldb -ldl -lm -lpthread -lc -lcrypt -lutil perllibs= libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libper gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so', d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE' cccdlflags='-fPIC' ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5', lddlflags='s Unicode/Normalize XS/A' Characteristics of this binary (from libperl): Compile-time options: DEBUGGING MULTIPLICITY USE_ITHREADS USE_LARGE_FILES PERL_IMPLICIT_CONTEXT Locally applied patches: MAINT18379 Built under linux Compiled at Sep 15 2003 10:03:52 @INC: /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 . ----------- Test Box #2 ----------- [jobs@rock jobs]$ uname -a Linux rock 2.4.21-15.ELsmp #1 SMP Thu Apr 22 00:18:24 EDT 2004 i686 i686 i386 GNU/Linux [jobs@rock jobs]$ perl -V Summary of my perl5 (revision 5 version 8 subversion 5) configuration: Platform: osname=linux, osvers=2.4.21-15.elsmp, archname=i686-linux uname='linux rock.knobias.com 2.4.21-15.elsmp #1 smp thu apr 22 00:18:24 edt 2004 i686 i686 i386 gnulinux ' config_args='-de' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-O2', cppflags='-fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='3.2.3 20030502 (Red Hat Linux 3.2.3-34)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.3.2.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: USE_LARGE_FILES Built under linux Compiled at Oct 19 2004 16:05:49 @INC: /usr/local/lib/perl5/5.8.5/i686-linux /usr/local/lib/perl5/5.8.5 /usr/local/lib/perl5/site_perl/5.8.5/i686-linux /usr/local/lib/perl5/site_perl/5.8.5 /usr/local/lib/perl5/site_perl . ---------------- How to Reproduce ---------------- file leak.pl #!/usr/bin/perl $| = 1; use strict; use XML::LibXML; my $xml = sprintf <<EOD; <?xml version="1.0"?> <blah> <blarg>this is blarg.</blarg> <blarf>this is blarf.</blarf> </blah> EOD my $parser = XML::LibXML->new(); for (my $x = 0; $x < 1000000; $x++) { my $doc = $parser->parse_string($xml); if ($x % 1000 == 0) { print "checkpoint $x\n"; } if ($x % 10000 == 0) { print " sleeping for 10\n"; sleep 10; } } Start up 2 shells into the same box. In one, run top. In the other, run the script from above. Filter top down to make the test script visible, and watch the process memory grow out of control.
valgrind has some interesting output from the test script: ==7165== 806193 bytes in 9953 blocks are definitely lost in loss record 26 of 27 ==7165== at 0x1B90354C: malloc (vg_replace_malloc.c:130) ==7165== by 0x1C0077B9: xmlSaveUri (uri.c:232) ==7165== by 0x1C00AFF9: xmlCanonicPath (uri.c:2221) ==7165== by 0x1C078004: xmlSAX2StartDocument (SAX2.c:882) ==7165== by 0x1BFF4844: xmlParseDocument (parser.c:8620) ==7165== by 0x1C1EDB79: XS_XML__LibXML__parse_string (in /usr/local/lib/perl5/site_perl/5.8.5/i686-linux/auto/XML/LibXML/LibXML.so) ==7165== by 0x80AC3DB: Perl_pp_entersub (in /usr/bin/perl) ==7165== by 0x80A603F: Perl_runops_standard (in /usr/bin/perl) ==7165== by 0x80610DD: S_run_body (in /usr/bin/perl) ==7165== by 0x8060ED5: perl_run (in /usr/bin/perl) ==7165== by 0x805E3F8: main (in /usr/bin/perl)
[guest - Fri May 20 11:15:44 2005]: Additional information on the problem ... XML::LibXML seems to have started leaking while parsing xml documents in v1.57. Rolled back from v1.58 to v1.57 and same leak was present. Rolled further back to v1.56 and the leak went away. This has now been verified on 3 different boxes: RH ES3 perl v5.8.0 libxml 2.6.22 RH ES3 (update 2) perl v5.8.5 libxml 2.6.16 RH 9 perl v5.8.0 libxml 2.6.11 each quit leaking when XML::LibXML was regressed to v1.56.
From: David Pashley <david [...] davidpashley.com>
This should fix the memory leak. diff -ur libxml-libxml-perl-1.58/LibXML.xs libxml-libxml-perl-1.58.new/LibXML.xs --- libxml-libxml-perl-1.58/LibXML.xs 2006-03-23 00:34:56.000000000 +0000 +++ libxml-libxml-perl-1.58.new/LibXML.xs 2006-03-23 00:33:36.000000000 +0000 @@ -976,6 +976,7 @@ if ( real_doc != NULL ) { recover = LibXML_get_recover(real_obj); + if (real_doc->URL) { xmlFree(real_doc->URL);} if ( directory == NULL ) { SV * newURI = sv_2mortal(newSVpvf("unknown-%12.12d", (void*)real_doc)); real_doc->URL = xmlStrdup((const xmlChar*)SvPV_nolen(newURI));
@@ -1324,6 +1325,7 @@ } xs_warn( "context created\n"); + if (ctxt->sax) { xmlFree(ctxt->sax);} ctxt->sax = PSaxGetHandler(); PmmSAXInitContext( ctxt, self ); xs_warn( "context initialized \n"); Fixes one more error and seems to be 88 bytes in size :)