Subject: | Segfault and double free on Debian Jessie and Ubuntu Utopic Unicorn (probably caused by using replaceNode) |
While preparing our code base for Debian Jessie, I ran into segmentation faults and double frees, and I currently assume that this happens when using replaceNode(). I already reported a bug in the Debian issue tracker [1], but haven't received a reply, yet (the segfault.pl version in that bug report doesn't crash as often as the attached one though). The issue also doesn't seem to be completely Debian-specific, as I can also reproduce it on the closely related Ubuntu Utopic Unicorn (14.10) and the slightly older Trusty Tahr (14.04 LTS, but only if I install XML-LibXML from CPAN, the version provided by Ubuntu (2.0108+dfsg-1) seems to work). I also tried various versions of XML-LibXML from CPAN on Debian Jessie and Ubuntu Utopic Unicorn, and it seems that from 2.0114 onwards, the problem is always there. When running the attached files on Debian Jessie (Perl v5.20.2, XMl-LibXML 2.0116+dfsg-1+b1, libxml2 2.9.1+dfsg1-5, all installed from packages, on x86_64), the output looks as follows:
$ perl segfault.pl
Segmentation fault
$ prove Debian_Jessie_double_free.t
Debian_Jessie_double_free.t .. *** Error in `/usr/bin/perl': double free or corruption (fasttop): 0x0000000001b012f0 ***
Debian_Jessie_double_free.t .. All 1 subtests passed
Test Summary Report
-------------------
Debian_Jessie_double_free.t (Wstat: 6 Tests: 1 Failed: 0)
Non-zero wait status: 6
Files=1, Tests=1, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.05 cusr 0.00 csys = 0.07 CPU)
Result: FAIL
For the segfault, I got this in the syslog:
perl[28012] segfault at 40 ip 00007f3a55607ced sp 00007fff2142f6a0 error 4 in LibXML.so[7f3a555bf000+69000]
Same, but this time with a local::lib and XML-LibXML 2.0118 installed from CPAN:
$ perl segfault.pl
*** Error in `perl': double free or corruption (fasttop): 0x0000000001e383e0 ***
Aborted
$ prove Debian_Jessie_double_free.t
Debian_Jessie_double_free.t .. *** Error in `/usr/bin/perl': double free or corruption (fasttop): 0x0000000000ac1140 ***
Debian_Jessie_double_free.t .. All 1 subtests passed
Test Summary Report
-------------------
Debian_Jessie_double_free.t (Wstat: 6 Tests: 1 Failed: 0)
Non-zero wait status: 6
Files=1, Tests=1, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.05 cusr 0.00 csys = 0.07 CPU)
Result: FAIL
Nearly the same, but when I ran the commands several times, I noticed that with the version from Debian, I nearly always get a segfault, while with the latest version from CPAN, I nearly always get a double free, and only occasionally a segfault.
One thing I noticed while playing with my test scripts is that inlining the get_node() function seems to avoid the crashes.
I already spotted #80521 in RT, but since I'm at least not explicitly using any DTD, I don't think that this is the same problem, which is why I'm creating a fresh issue.
Kind regards
Manfred
[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780369
Subject: | Debian_Jessie_double_free.t |
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string(<<'EOXML');
<?xml version="1.0" encoding="UTF-8"?>
<root-element><settings/></root-element>
EOXML
my $expected = <<'EOXML';
<?xml version="1.0" encoding="UTF-8"?>
<root-element><settings><root/></settings></root-element>
EOXML
my $doc2 = XML::LibXML::Document->new('1.0', 'UTF-8');
my $new_node = $doc2->createElement('root');
$doc2->setDocumentElement($new_node);
my $node = get_node($doc);
#$doc->adoptNode($new_node);
$node->replaceNode($new_node);
my $str = $doc->toString();
# diag $str;
is($str, $expected);
done_testing;
sub get_node {
my ($doc) = @_;
my $parent = $doc->documentElement()->firstChild();
my $node = $doc->createElement('my-settings');
$parent->appendChild($node);
return $node;
}
1;
Subject: | segfault.pl |
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string(<<'EOXML');
<?xml version="1.0" encoding="UTF-8"?>
<root-element><settings/></root-element>
EOXML
my $doc2 = XML::LibXML::Document->new('1.0', 'UTF-8');
my $new_node = $doc2->createElement('root');
$doc2->setDocumentElement($new_node);
my $node = get_node($doc);
#$doc->adoptNode($new_node);
$node->replaceNode($new_node);
my $str = $doc->toString();
#warn $str;
sub get_node {
my ($doc) = @_;
my $parent = $doc->documentElement()->firstChild();
my $node = $doc->createElement('my-settings');
$parent->appendChild($node);
return $node;
}
1;