Subject: | Leak / Circular Reference |
I found a circular Refernce between XML::LibXML and XML::LibXML::SAX
It can be caused by the following script:
use XML::SAX;
$XML::SAX::ParserPackage = "XML::LibXML::SAX";
use XML::Simple;
for (1..3) {
my $c = XML::Simple->new->XMLin("<xml>z</xml>");
};
*UNIVERSAL::DESTROY = sub {warn $_[0]};
You will see the amount of DESTROY " during global destruction " grows with the amount of loops.
running XML::Simple with $XML::SAX::ParserPackage = "XML::SAX::PurePerl"; does not cause the problem.
I was able to get a Dump of the remining Object:
$VAR1 = bless(
{ 'XML_LIBXML_KEEP_BLANKS' => 1,
'_State_' => 0,
'SAX_ELSTACK' => [],
'SAX' => { 'State' => 0 },
'HANDLER' => bless(
{ 'XML::SAX::Base::Features' => { 'http://xml.org/sax/features/namespaces' => 1 },
'Handler' => bless(
{ 'nocollapse' => 1,
'def_opt' => {},
'opt' => {
'normalisespace' => 0,
'rootname' => 'opt',
'parseropts' => [],
'keyattr' => [
'name',
'key',
'id'
],
'forcearray' => 0,
'contentkey' => 'content',
'searchpath' => []
}
}, 'XML::Simple' ),
'Methods' => {
'end_element' => sub { "DUMMY" },
'xml_decl' => sub { "DUMMY" },
'start_document' => sub { "DUMMY" },
'end_document' => sub { "DUMMY" },
'characters' => sub { "DUMMY" },
'start_element' => sub { "DUMMY" }
},
'ParserOptions' => bless( {
'ParseFunc' => sub { "DUMMY" },
'LibParser' => $VAR1,
'ParseFuncParam' => '<xml>z</xml>'
}, 'XML::LibXML::SAX' ),
'ParseOptions' => undef
}, 'XML::LibXML::SAX' )
}, 'XML::LibXML' );
You can see that ParserOptions->{LibParser} points back to $VAR1
This happens in
package XML::LibXML::SAX;
$VERSION = '1.00';
sub _parse {
my $self = shift;
my $args = bless $self->{ParserOptions}, ref($self);
$args->{LibParser}->set_handler( $self );
$args->{ParseFunc}->($args->{LibParser}, $args->{ParseFuncParam});
if ( $args->{LibParser}->{SAX}->{State} == 1 ) {
croak( "SAX Exception not implemented, yet; Data ended before document ended\n" );
}
return $self->end_document({});
}
In the 4th line, the call: ->set_handler($self) creates this reference. I have notdebugged that any further, but either here, or on the other end of the circular ref, should probably be a weak reference, so that a proper cleanup is guaranteed, in any context.
I am experience this on several FreeBSD configurations, with varios versions of perl:
perl -v
This is perl, v5.8.6 built for i386-freebsd-64int
perl -v
This is perl, v5.8.0 built for i386-freebsd
I have the following Versions of CPAN mudules:
XML::LibXML => 1.58
XML::LibXML::Common => 0.13
XML::LibXML::SAX => 1.00
XML::SAX => 0.12
XML::SAX::Base => 1.04
XML::SAX::Exception => 1.01
XML::SAX::ParserFactory => 1.01
XML::Simple => 2.13 # happens with 2.14 too
Please apologise, that I have not tracked down the problem, without the use of XML::Simple. but all the above point to a problem insid XML::LibXML