Skip to content
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

Open
ian-kent opened this issue Jul 15, 2013 · 5 comments
Open

Segmentation fault (core dumped) when rendering templates #85

ian-kent opened this issue Jul 15, 2013 · 5 comments

Comments

@ian-kent
Copy link

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.

@syohex
Copy link
Contributor

syohex commented Jul 15, 2013

Note: It causes infinite loop.

Perl_call_sv => Perl_pp_entersub => XS_Text__Xslate__macrocall => tx_proccall => tx_funcall => tx_call_sv 
=> Perl_call_sv ....

GDB log

% gdb --args perl -I. block.pl
(gdb) run
Starting program: /home/syohei/perl5/perlbrew/perls/perl-5.16.1/bin/perl -I. block.pl
Text::Xslate: Undefined function is called on macro (/home/syohei/tmp/gomi/xslate-block/test.tx:2) at block.pl line 37.
----------------------------------------------------------------------------
Inline block with render
: $c.block(-> {
    : count()
----------------------------------------------------------------------------
Text::Xslate: Use of uninitialized value in concatenation (.) or string at Block.pm line 10.
 (/home/syohei/tmp/gomi/xslate-block/test.tx:2) at block.pl line 37.
----------------------------------------------------------------------------
Inline block with render
: $c.block(-> {
    : count()
----------------------------------------------------------------------------

Program received signal SIGSEGV, Segmentation fault.
0x0807ca2a in Perl_call_sv ()
(gdb) bt
#0  0x0807ca2a in Perl_call_sv ()
#1  0x0032570f in tx_call_sv ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#2  0x00328d85 in tx_funcall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#3  0x00329d5b in tx_proccall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#4  0x00329e35 in XS_Text__Xslate__macrocall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#5  0x080dd7a9 in Perl_pp_entersub ()
#6  0x0807cf5b in Perl_call_sv ()
#7  0x0032570f in tx_call_sv ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#8  0x00328d85 in tx_funcall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#9  0x00329d5b in tx_proccall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#10 0x00329e35 in XS_Text__Xslate__macrocall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#11 0x080dd7a9 in Perl_pp_entersub ()
....
#117918 0x0807cf5b in Perl_call_sv ()
#117919 0x0032570f in tx_call_sv ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117920 0x00328d85 in tx_funcall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117921 0x00329d5b in tx_proccall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117922 0x00329e35 in XS_Text__Xslate__macrocall ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117923 0x080dd7a9 in Perl_pp_entersub ()
#117924 0x080dc6b3 in Perl_runops_standard ()
#117925 0x0807cdba in Perl_call_sv ()
#117926 0x0032570f in tx_call_sv ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117927 0x00325aa4 in tx_fetch ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117928 0x003267ca in tx_runops ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117929 0x00328750 in tx_execute ()
   from /home/syohei/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/i686-linux/auto/Text/Xslate/Xslate.so
#117930 0x00000000 in ?? ()
(gdb)

@ian-kent
Copy link
Author

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);

@ian-kent
Copy link
Author

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:

: $c.test(-> {
Rendering <: count() :>
: }).render

@ian-kent
Copy link
Author

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:
https://gist.github.com/ian-kent/6002248

Whereas this one doesn't:
https://gist.github.com/ian-kent/6002258

This ones an interesting one - doesn't segfault, but does give undefined function warnings:
https://gist.github.com/ian-kent/6002292

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

@ian-kent
Copy link
Author

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.

@ghost ghost assigned gfx Jul 16, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants