-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Segmentation fault (core dumped) when rendering templates #85
Comments
Note: It causes infinite loop.
GDB log
|
On a course atm, but this example demonstrates it failing. Comment out 69-74, then uncomment 59-61. All works. Uncomment 62-64, causes an undefined function. Finally uncomment 65-67 and it segfaults. If I reuse the same object (as in 69-74) it works?! package test;
sub new {
my ($package, %args) = @_;
return bless {
%args
}, 'test';
}
sub render {
return shift->{block}->();
}
package helper;
sub new {
my ($package, %args) = @_;
return bless {
%args
}, 'helper';
}
sub test {
my ($self) = @_;
my $block = pop @_;
return test->new(block => $block);
}
package main;
#!/usr/bin/env perl
use Data::Dumper;
use Text::Xslate;
my $count = 0;
my $xslate = Text::Xslate->new(
function => {
count => sub {
++$count;
}
}
);
my $content = <<EOF
: \$c.test(-> {
Rendering <: count() :>
: }).render
EOF
;
print $xslate->render_string($content, {
c => helper->new
});
print $xslate->render_string($content, {
c => helper->new
});
#print $xslate->render('test2.tx', {
# c => helper->new
#});
#print $xslate->render('test2.tx', {
# c => helper->new
#});
#print $xslate->render('test2.tx', {
# c => helper->new
#});
my $params = {
c => helper->new
};
print $xslate->render('test2.tx', $params);
print $xslate->render('test2.tx', $params);
print $xslate->render('test2.tx', $params); |
Got a bit further... it looks like a cache problem, with cache 0 or render_string it doesn't happen. A more concise example: package test;
sub new {
my ($package, %args) = @_;
return bless {
%args
}, 'test';
}
sub render {
return shift->{block}->();
}
package helper;
sub new {
my ($package, %args) = @_;
return bless {
%args
}, 'helper';
}
sub test {
my ($self) = @_;
my $block = pop @_;
return test->new(block => $block);
}
package main;
use Data::Dumper;
use Text::Xslate;
my $count = 0;
my $xslate = Text::Xslate->new(
cache => 1,
function => {
count => sub {
++$count;
}
}
);
my $params = {
c => helper->new
};
# works with cache 0/1/2
print $xslate->render('test.tx', $params );
# works with cache 0, undefined function with cache 1/2
print $xslate->render('test.tx', $params );
# works with cache 0, segfault for cache 1/2
print $xslate->render('test.tx', $params ); And test.tx:
|
And a bit further... it looks like a blessed hash is enough to break it, but multiple levels of blessed hash for a segfault (still requires caching to be on) This one still causes a segfault: Whereas this one doesn't: This ones an interesting one - doesn't segfault, but does give undefined function warnings: edit: also worth mentioning it doesn't occur using Text::Xslate::PP edit 2: it also happens if I use templates from a hash: https://gist.github.com/ian-kent/6002917 |
A bit more info: https://gist.github.com/ian-kent/6003638 It seems the difference between it working and it erroring is creating new objects for each render which capture the macro. Strangely, changing the constructor syntax in the objects also seems to make it error. If the syntax on the object constructor is changed, and then we use a new object each time, it errors again. But if we use the same object each time, it then segfaults. |
Could you have a look at the example here: https://github.com/ian-kent/xslate-block
If you run block.pl, you'll see it segfault on the second attempt at rendering the example template (complaining about undefined function called on macro), despite the first render giving the expected output.
If you uncomment lines 24-30 in block.pl to create a new instance of Xslate, the template will then render a second time without any problem.
If you uncomment line 34, Xslate gives even stranger output, but at least renders a template and doesn't segfault.
However, a similar (but less complex) example in macro.pl doesn't cause the same bug, regardless of how many times its called.
The text was updated successfully, but these errors were encountered: